I am trying to generate several random numbers according to some conditions, but the way I have it implemented, it won't run.
The conditions are:
CheckConditions[\[Lambda]1_, \[Lambda]2_, \[Lambda]6_, \[Lambda]7_, \
\[Lambda]8_, \[Lambda]3_, \[Lambda]4_, \[Lambda]5_, v1_, v2_, v1s_,
v2s_, vS_] :=
Module[{cond1, cond2, cond3, cond4, cond5, cond6, cond7, cond8,
cond9, cond10, cond11},
cond1 = \[Lambda]1 > 0 && \[Lambda]2 > 0 && \[Lambda]6 > 0;
cond2 = Sqrt[Abs[\[Lambda]1 \[Lambda]6]] + \[Lambda]7 > 0;
cond3 = Sqrt[Abs[\[Lambda]2 \[Lambda]6]] + \[Lambda]8 > 0;
cond4 =
Sqrt[Abs[\[Lambda]1 \[Lambda]2]] + \[Lambda]3 +
Min[\[Lambda]4 - Abs[\[Lambda]5], 0] > 0;
cond5 = \[Lambda]7 + Sqrt[Abs[\[Lambda]1/\[Lambda]2]] \[Lambda]8 >=
0;
cond6 = \[Lambda]2 \[Lambda]6 >= \[Lambda]8^2;
cond7 =
Sqrt[Abs[\[Lambda]1 \[Lambda]6]] > -\[Lambda]7 >=
Sqrt[Abs[\[Lambda]1/\[Lambda]2]] \[Lambda]8;
cond8 =
Sqrt[Abs[(\[Lambda]7^2 - \[Lambda]1 \[Lambda]6) (\[Lambda]8^2 - \
\[Lambda]2 \[Lambda]6)]] > \[Lambda]7 \[Lambda]8 - (Min[\[Lambda]4 -
Abs[\[Lambda]5], 0] + \[Lambda]3) \[Lambda]6;
cond9 = v1^2 + v2^2 == 246^2;
cond10 = v1s^2 + v2s^2 == 246^2;
cond11 = 1 <= vS <= 3*10^3;
cond1 && cond2 && cond3 && cond4 && cond5 && cond6 && cond7 &&
cond8 && cond9 && cond10 && cond11]
And the part of the code regarding the generation is:
ParameterGenerator[] :=
Module[{\[Lambda]1, \[Lambda]2, \[Lambda]3, \[Lambda]4, \[Lambda]5, \
\[Lambda]6, \[Lambda]7, \[Lambda]8, v1, v2, v1s, v2s, vS, m12, m11,
m22, mS, VwithVS, VwithoutVS, diff, conditions},
(*Generate parameters and check conditions until they are satisfied*)
While[True,
{\[Lambda]1, \[Lambda]2, \[Lambda]6} = RandomReal[{0, 1}, 3];
{\[Lambda]7, \[Lambda]8, \[Lambda]3, \[Lambda]4, \[Lambda]5} =
RandomReal[{-1, 1}, 5];
v1 = RandomReal[{0, 246}];
v2 = Sqrt[246^2 - v1^2];
v1s = RandomReal[{0, 246}];
v2s = Sqrt[246^2 - v1s^2];
vS = RandomReal[{1, 3*10^3}];
m12 = RandomReal[{0, Sqrt[5*10^5]}];
(*Check if the generated parameters satisfy the conditions*)
conditions =
CheckConditions[\[Lambda]1, \[Lambda]2, \[Lambda]6, \[Lambda]7, \
\[Lambda]8, \[Lambda]3, \[Lambda]4, \[Lambda]5, v1, v2, v1s, v2s,
vS];
Print["Conditions: ", conditions];
If[conditions,
Print["Parameters: ", {\[Lambda]1, \[Lambda]2, \[Lambda]6, \
\[Lambda]7, \[Lambda]8, \[Lambda]3, \[Lambda]4, \[Lambda]5, v1, v2,
v1s, v2s, vS}];
Break[];];
];
This function has more code afterwards, but that is not relevant to the matter. I have tried without the while True part, but it wouldn't agree with the conditions.Is there any way to optimize this loop?
Print
statements; that will make things much faster. $\endgroup$Compile
. Without thePrint
statements, this can basically be run in a small external library with almost no callbacks to Mathematica's main kernel. You better inlineCheckConditions
manually, though. $\endgroup$And
.And
evaluates its arguments from left to right; as soon as one argument isFalse
, it returnsFalse
without evaluating the other ones. That's also what the compiler will do. $\endgroup$And
shortcircuits, you'd probably get better performance if you didn't precompute all of the conditions before applyingAnd
to them. Once you change that, you can remove some of the redundant checks. For example, after you've already checked thatl1
andl6
are positive you don't need theAbs
inSqrt[Abs[l1 l6]] + l7 > 0
. Or another example is the bit of redundancy betweencond3
andcons6
, which I assume you can clean/simplify. But even after all of that, you're stuck with the fact thatcond5
andcond7
force you into havingl7
andl8
be0
. $\endgroup$l7
andl8
aren't0
, then nothing else matters, and it's unlikely that you'll randomly choose both of those to be0
. $\endgroup$