कई बिंदुओं पर एक फ़ंक्शन का मूल्यांकन करने का इष्टतम तरीका
मेरे पिछले प्रश्न पर यह गुल्लक-पीठ: पैरामीटर स्थान खोज दिनचर्या बहुत तेज़ है?
मैं कई बिंदुओं पर एक प्रतीकात्मक सूची का मूल्यांकन करने के लिए एक तेज़ तरीके की तलाश कर रहा हूं। तो आइए हम बताते हैं जैसे कि प्रतीकात्मक अभिव्यक्तियों की एक सूची है
ListA={a*b*c>0, a*b*(c+1)>0, a*b*(c-1)>0, etc.}
और फार्म के tuples की एक सूची
ListB={{1,1,1}, {1,1,2}, {1,2,1}, {1,2,2}< etc.}
और मैं ListB के प्रत्येक टपल पर ListA का मूल्यांकन करना चाहता हूं
ListA/.Thread[{a,b,c} -> ListB[[1]]]
ListA /.Thread[{a,b,c} -> ListB[[2]]]
अब, मेरी सूची में दसियों हजार अंक हो सकते हैं और प्रत्येक अभिव्यक्ति सौ से अधिक हो सकती है। माई लिस्टबी भी गेनॉर्मस हो सकता है, जैसे कि दसियों अंकों के ऊपर। लेकिन प्रत्येक टपल में केवल ~ 5 तत्व होते हैं और मैंने इसे लगभग 100-1000 टुपल्स के आकार में चुना है। मेरा सवाल यह है कि इस प्रकार के प्रतिस्थापन / संघ को जल्दी से करने का सबसे अच्छा तरीका क्या होगा?
मेरे पहले प्रयास का उपयोग किया गया था ParallelMap
लेकिन इसने अभी भी उम्र ली। फिर मैंने देखा Associations
और इसने समय को घटा दिया लेकिन लिस्ट बी के एक तत्व के प्रत्येक प्रतिस्थापन में अभी भी 1.5 - 2 सेकंड लगते हैं, जिसे मुझे काफी कम करना होगा। यहाँ संदर्भ के लिए एक MWE है:
func = (-2^(1 - px) (-1 + px) px Coth[
rx sx]^2 (-2 sx y Sech[sx (-rx + x^2 + y^2)]^2 +
2 sx y Sech[sx (rx + x^2 + y^2)]^2)^2 (Coth[
rx sx] (-Tanh[sx (-rx + x^2 + y^2)] +
Tanh[sx (rx + x^2 + y^2)]))^(-2 + px) -
2^(1 - px) px Coth[
rx sx] (Coth[
rx sx] (-Tanh[sx (-rx + x^2 + y^2)] +
Tanh[sx (rx + x^2 + y^2)]))^(-1 +
px) (-2 sx Sech[sx (-rx + x^2 + y^2)]^2 +
2 sx Sech[sx (rx + x^2 + y^2)]^2 +
8 sx^2 y^2 Sech[sx (-rx + x^2 + y^2)]^2 Tanh[
sx (-rx + x^2 + y^2)] -
8 sx^2 y^2 Sech[sx (rx + x^2 + y^2)]^2 Tanh[
sx (rx + x^2 + y^2)]) +
2^-px (-1 + px) px Coth[
rx sx]^2 (-2 sx y Sech[sx (-R - rx + x^2 + y^2)]^2 +
2 sx y Sech[sx (-R + rx + x^2 + y^2)]^2)^2 (Coth[
rx sx] (-Tanh[sx (-R - rx + x^2 + y^2)] +
Tanh[sx (-R + rx + x^2 + y^2)]))^(-2 + px) +
2^-px px Coth[
rx sx] (Coth[
rx sx] (-Tanh[sx (-R - rx + x^2 + y^2)] +
Tanh[sx (-R + rx + x^2 + y^2)]))^(-1 +
px) (-2 sx Sech[sx (-R - rx + x^2 + y^2)]^2 +
2 sx Sech[sx (-R + rx + x^2 + y^2)]^2 +
8 sx^2 y^2 Sech[sx (-R - rx + x^2 + y^2)]^2 Tanh[
sx (-R - rx + x^2 + y^2)] -
8 sx^2 y^2 Sech[sx (-R + rx + x^2 + y^2)]^2 Tanh[
sx (-R + rx + x^2 + y^2)]) +
2^-px (-1 + px) px Coth[
rx sx]^2 (-2 sx y Sech[sx (R - rx + x^2 + y^2)]^2 +
2 sx y Sech[sx (R + rx + x^2 + y^2)]^2)^2 (Coth[
rx sx] (-Tanh[sx (R - rx + x^2 + y^2)] +
Tanh[sx (R + rx + x^2 + y^2)]))^(-2 + px) +
2^-px px Coth[
rx sx] (Coth[
rx sx] (-Tanh[sx (R - rx + x^2 + y^2)] +
Tanh[sx (R + rx + x^2 + y^2)]))^(-1 +
px) (-2 sx Sech[sx (R - rx + x^2 + y^2)]^2 +
2 sx Sech[sx (R + rx + x^2 + y^2)]^2 +
8 sx^2 y^2 Sech[sx (R - rx + x^2 + y^2)]^2 Tanh[
sx (R - rx + x^2 + y^2)] -
8 sx^2 y^2 Sech[sx (R + rx + x^2 + y^2)]^2 Tanh[
sx (R + rx + x^2 + y^2)]));
parameters = {px, pz, R, rx, rz, sx, sz}
variables = {x, y, z}
Quantifier[coords_, params_] :=
Function[Evaluate@Join[variables, parameters], Evaluate@(func > 0)][
Sequence @@ Join[coords, params]]
SpaceA = Tuples[Range[-2, 2, 0.2], 3];
ListA = Quantifier[#1, parameters] & /@ SpaceA;
ListB = Tuples[Range[1, 4, 0.4], 7];
(*ListB contains~2 million elements*)
अब, मूल्यांकन ListA
अधिक की ListB
तरह होगा
(AllTrue[ListA /. Thread[parameters -> #], TrueQ]) & /@ ListB
(*Careful running this, it will probably take a few months :( *)
मेरी समस्या यह है कि एक भी संघ की तरह
ListA/.Thread[parameters->{1,1,1,1,1,1,1}]
लगभग 2 सेकंड लगते हैं। इसलिए इसे ~ 2 मिलियन अंकों की सूची में दोहराने से एक सदी लग जाएगी।
एक संकलित समारोह उपयोगी होगा? मुझे संकलन की कार्यक्षमता का उपयोग करने का अधिक अनुभव नहीं है, इसलिए मैं सोच रहा हूं कि क्या यह पता लगाने के लिए लाभप्रद होगा। मैं किसी भी अंतर्दृष्टि की सराहना करता हूं!
अपडेट करें
@Flinty सुझाव के लिए धन्यवाद, उपयोग करने से With
लगता है कि असाइनमेंट में काफी तेजी आई है। एक छोटा समय प्रयोग प्रयोग:
यहाँ, ऊपर MWE में QuantifieroverSpace
मेल खाती है ListA
।
ClearAll[\[Epsilon], px, pz, R, rx, rz, sx, sz]
ByteCount[QuantifieroverSpace]
With[{\[Epsilon] = 2, px = 1, pz = 5, R = 1, rx = 2, rz = 2, sx = 2,
sz = 2},
Evaluate@AllTrue[QuantifieroverSpace, TrueQ]] // Timing
AllTrue[QuantifieroverSpace /.
Thread[{\[Epsilon], px, pz, R, rx, rz, sx, sz} -> {2, 1, 5, 1, 2,
2, 2, 2}], TrueQ] // Timing
(*126992696*)
(*{0.000026, False}*)
(*{2.08846, False}*)
इसलिए With
इसके बजाय का उपयोग करना ReplaceAll
तीव्रता के कई आदेश हैं, जो दिलचस्प है। मैं इसे अपनी खोज रूटीन में लागू करूंगा और देखूंगा कि इसमें कितना सुधार हुआ है।
अपडेट २
तो मेरा अगला मुद्दा यह है कि मुझे तर्कों की With
संख्या के लिए पहले तर्क की आवश्यकता है, अर्थात इसे {a = 1, b = 1, c = 1} या 3 चर सेट में लेने में सक्षम होना चाहिए। एक अलग संख्या जैसे {a = 1}। मेरा पहला हालांकि ऐसा कुछ करना होगा
With[
{Thread[SymbolList = ArrayofValues]},
...
]
लेकिन गणितज्ञ ArrayofValues
प्रतीकों में मानों को असाइन कर रहा है SymbolList
ताकि a
उदाहरण के लिए चर का मान 1 हो। मैंने तब कोशिश की थी
init = MapThread[HoldForm[#1=#2]&, {SymbolList, ArrayofValues}];
With[
Evaluate@ReleaseHold[init],
...
]
लेकिन यह वही काम करता है, जो प्रतीकों को मान प्रदान करता है। दिलचस्प है, गणितज्ञ अभी भी with
पहले तर्क में मूल्यों का उपयोग करके अभिव्यक्ति को निष्पादित करता है, लेकिन इसके प्रतीक को मूल्य अभी भी असाइन कर रहा है, जो कि अगर मैं असाइनमेंट को पूर्ववत करना चाहता था, तो मेरी खोज दिनचर्या के निष्पादन को धीमा कर देगा। मुझे किसी तरह Set
आईएनजी असाइनमेंट को रोकने की जरूरत है, लेकिन अभी भी a=1
एक तरह से वेरिएबल्स की संख्या को गतिशील बनाए रखता है ।
अपडेट ३
अच्छी तरह से आगे के निरीक्षण पर, मुझे लगा कि With
इतना तेज क्यों प्रतीत होता है। इसका कारण यह है कि वास्तव में अभिव्यक्ति में पहले तर्क के मूल्यों को सदस्यता नहीं दी जाती है। उदाहरण के लिए,
a = {l, s};
With[{l = 3, s = 12},
Print[Evaluate[a]]
];
(*{l,s}*)
इसलिए मुझे लगता है कि मैं एक बड़े प्रतीकात्मक सरणी के अंदर मापदंडों को मान असाइन करने का एक तेज़ तरीका खोजने की कोशिश कर रहा हूँ।
जवाब
यह केवल एक आंशिक उत्तर है, लेकिन ...
आपका कार्य बहुत जटिल है, और इसे तेज़ करना शायद इससे अधिक महत्वपूर्ण है कि आप इसे कैसे मान देते हैं। Compileयहाँ आपका दोस्त है
cfunc = Compile @@ {Join[variables, parameters], func,
CompilationTarget -> "C", "RuntimeOptions" -> "Speed",
RuntimeAttributes -> {Listable}}
RepeatedTiming[AllTrue[cfunc @@ Join[SpaceA // Transpose, ListB[[1]]], Positive]]
{0.0051, False}
की एक पंक्ति के लिए 5ms पर ListB
, यह अभी भी एक लंबा समय लेने वाला है, हालांकि यह अधिक यथार्थवादी हो रहा है।