स्वचालित अवकलन: Difference between revisions

From Vigyanwiki
No edit summary
Line 47: Line 47:
उत्क्रम संचयन की तुलना में, अग्रगामी संचयन स्वाभाविक रूप से लागू करना आसान है क्योंकि अवकलज सूचना का प्रवाह मूल्यांकन के क्रम के साथ मेल खाता है। प्रत्येक चर <math>w_i</math> को इसके अवकलज <math>\dot w_i</math> (संख्यात्मक मान के रूप में संग्रहीत, प्रतीकात्मक व्यंजक नहीं),
उत्क्रम संचयन की तुलना में, अग्रगामी संचयन स्वाभाविक रूप से लागू करना आसान है क्योंकि अवकलज सूचना का प्रवाह मूल्यांकन के क्रम के साथ मेल खाता है। प्रत्येक चर <math>w_i</math> को इसके अवकलज <math>\dot w_i</math> (संख्यात्मक मान के रूप में संग्रहीत, प्रतीकात्मक व्यंजक नहीं),
<math display="block">\dot w_i = \frac{\partial w_i}{\partial x}</math>के साथ संवर्धित किया गया है ,जैसा कि बिंदु द्वारा दर्शाया गया है। फिर मूल्यांकन चरणों के साथ अवकलज की गणना की जाती है और श्रृंखला नियम के माध्यम से अन्य अवकलज के साथ जोड़ा जाता है।
<math display="block">\dot w_i = \frac{\partial w_i}{\partial x}</math>के साथ संवर्धित किया गया है ,जैसा कि बिंदु द्वारा दर्शाया गया है। फिर मूल्यांकन चरणों के साथ अवकलज की गणना की जाती है और श्रृंखला नियम के माध्यम से अन्य अवकलज के साथ जोड़ा जाता है।
श्रृंखला नियम का उपयोग करते हुए, यदि <math>w_i</math> के पास अभिकलनीय ग्राफ़ में पूर्ववर्ती हैं, तो  
श्रृंखला नियम का उपयोग करते हुए, if <math>w_i</math> के पास अभिकलनीय ग्राफ़ में पूर्ववर्ती हैं, तो  
:<math>\dot w_i = \sum_{j \in \{\text{predecessors of i}\}} \frac{\partial w_i}{\partial w_j} \dot w_j</math>
:<math>\dot w_i = \sum_{j \in \{\text{predecessors of i}\}} \frac{\partial w_i}{\partial w_j} \dot w_j</math>


Line 85: Line 85:


===== छद्म कोड =====
===== छद्म कोड =====
अग्रगामी संचयन एक पास में, फलन और अवकलज (लेकिन केवल एक स्वतंत्र चर के लिए) की गणना करता है। संबंधित विधि कॉल एक चर V के संबंध में व्यंजक Z को प्राप्त करने की अपेक्षा करती है। विधि मूल्यांकन किए गए फलन और इसके अवकलन की एक जोड़ी की पुनरावृत्ति है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है। यदि इस चर के संबंध में अवकलज का अनुरोध किया जाता है, तो इसका अवकलज 1, 0 होगा अन्यथा। फिर आंशिक फलन के साथ-साथ आंशिक अवकलज का मूल्यांकन किया जाता है।<ref name="demm22">{{cite journal|author = Maximilian E. Schüle, Maximilian Springer, [[Alfons Kemper]], [[Thomas Neumann]] |title=स्वचालित विभेदन के लिए एलएलवीएम कोड अनुकूलन|journal=DEEM '22: Proceedings of the Sixth Workshop on Data Management for End-To-End Machine Learning|date=2022|doi = 10.1145/3533028.3533302|language=English}}</ref>
अग्रगामी संचयन एक पास में, फलन और अवकलज (लेकिन केवल एक स्वतंत्र चर के लिए) की गणना करता है। संबंधित विधि कॉल एक चर V के संबंध में व्यंजक Z को प्राप्त करने की अपेक्षा करती है। विधि मूल्यांकन किए गए फलन और इसके अवकलन की एक जोड़ी की return है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है। if इस चर के संबंध में अवकलज का अनुरोध किया जाता है, तो इसका अवकलज 1, 0 होगा else। फिर आंशिक फलन के साथ-साथ आंशिक अवकलज का मूल्यांकन किया जाता है।<ref name="demm22">{{cite journal|author = Maximilian E. Schüle, Maximilian Springer, [[Alfons Kemper]], [[Thomas Neumann]] |title=स्वचालित विभेदन के लिए एलएलवीएम कोड अनुकूलन|journal=DEEM '22: Proceedings of the Sixth Workshop on Data Management for End-To-End Machine Learning|date=2022|doi = 10.1145/3533028.3533302|language=English}}</ref>
  tuple<[[float,float]]>eval(Expression Z, Expression V) { [[यदि]] चर(Z) है
  tuple<[[float,float]]>eval(Expression Z, Expression V) { [[यदि|if]] isVariable (Z)
       यदि (Z=V) [[पुनरावृत्ति]] {valueOf(Z),1};
       if (Z=V) [[पुनरावृत्ति|return]] {valueOf(Z),1};
       [[अन्यथा पुनरावृत्ति]] {valueOf(Z),0};
       [[अन्यथा पुनरावृत्ति|else return]] {valueOf(Z),0};
   [[अन्यथा यदि]] (Z = X + Y)
   [[अन्यथा यदि|else if]] (Z = X + Y)
       {x,x'} = eval(X,V);
       {x,x'} = eval(X,V);
       {y,y'} = eval(Y,V);
       {y,y'} = eval(Y,V);
       पुनरावृत्ति {x+y, x'+y'};
       return {x+y, x'+y'};
   अन्यथा यदि (Z = X - Y)
   else if (Z = X - Y)
       {x,x'} = eval(X,V);
       {x,x'} = eval(X,V);
       {y,y'} = eval(Y,V);
       {y,y'} = eval(Y,V);
       पुनरावृत्ति {x-y, x'-y'};
       return {x-y, x'-y'};
   अन्यथा यदि (Z = X * Y)
   else if (Z = X * Y)
       {x,x'} = eval(X,V);
       {x,x'} = eval(X,V);
       {y,y'} = eval(Y,V);
       {y,y'} = eval(Y,V);
       पुनरावृत्ति {x*y, x'*y+x*y'};                                               
       return {x*y, x'*y+x*y'};                                               
===== सी++ =====
===== सी++ =====
  #[[include]] <iostream>
  #[[include]] <iostream>
Line 113: Line 113:
   Mul m1(&x,&z); Mul m2(&y,&z); Plus p(&m1,&m2); // x*z+y*z
   Mul m1(&x,&z); Mul m2(&y,&z); Plus p(&m1,&m2); // x*z+y*z
   std,,cout << x, << p.eval(dict,&x).d << , << y, << p.eval(dict,&y).d << , << z, << p. eval(dict,&z).d << std,,endl;
   std,,cout << x, << p.eval(dict,&x).d << , << y, << p.eval(dict,&y).d << , << z, << p. eval(dict,&z).d << std,,endl;
   पुनरावृत्ति 0;
   return 0;
=== उत्क्रम संचयन ===
=== उत्क्रम संचयन ===
उत्क्रम संचयन एडी में, अवकलित किए जाने वाले आश्रित चर को तय किया जाता है और अवकलज की गणना प्रत्येक उप-[[व्यंजक]] के संबंध में पुनरावर्ती रूप से की जाती है। कलम और कागज की गणना में, बाहरी फलनो के अवकलज को श्रृंखला नियम में बार-बार प्रतिस्थापित किया जाता है,
उत्क्रम संचयन एडी में, अवकलित किए जाने वाले आश्रित चर को तय किया जाता है और अवकलज की गणना प्रत्येक उप-[[व्यंजक]] के संबंध में पुनरावर्ती रूप से की जाती है। कलम और कागज की गणना में, बाहरी फलनो के अवकलज को श्रृंखला नियम में बार-बार प्रतिस्थापित किया जाता है,
Line 125: Line 125:
उत्क्रम संचयन में, ब्याज की मात्रा सहायक होती है, जिसे एक बार <math>\bar w_i</math>से दर्शाया जाता है, यह उपव्यंजक <math>w_i</math> के संबंध में चुने गए आश्रित चर का अवकलज है,
उत्क्रम संचयन में, ब्याज की मात्रा सहायक होती है, जिसे एक बार <math>\bar w_i</math>से दर्शाया जाता है, यह उपव्यंजक <math>w_i</math> के संबंध में चुने गए आश्रित चर का अवकलज है,
<math display="block">\bar w_i = \frac{\partial y}{\partial w_i}</math>
<math display="block">\bar w_i = \frac{\partial y}{\partial w_i}</math>
श्रृंखला नियम का उपयोग करते हुए, यदि <math>w_i</math> के पासअभिकलनीय ग्राफ़ में परवर्ती हैं, तो  
श्रृंखला नियम का उपयोग करते हुए, if <math>w_i</math> के पासअभिकलनीय ग्राफ़ में परवर्ती हैं, तो  
:<math>\bar w_i = \sum_{j \in \{\text{successors of i}\}} \bar w_j \frac{\partial w_j}{\partial w_i}</math>
:<math>\bar w_i = \sum_{j \in \{\text{successors of i}\}} \bar w_j \frac{\partial w_j}{\partial w_i}</math>
उत्क्रम संचयन श्रृंखला नियम को बाहर से अंदर तक, या चित्र 3 में अभिकलनीय ग्राफ की स्थिति में, ऊपर से नीचे तक चंक्रमण करता है। उदाहरण फलन अदिश-मूल्यवान है, और इस प्रकार अवकलज गणना के लिए केवल एक सीड है, और (दो-घटक) प्रवणता की गणना करने के लिए अभिकलनीय ग्राफ के केवल एक स्वीप की आवश्यकता होती है। अग्रगामी संचयन की तुलना में यह केवल [[आधा काम]] है, लेकिन उत्क्रम संचयन के लिए मध्यवर्ती चर {{math|''w''<sub>''i''</sub>}} के भंडारण की आवश्यकता होती है जो उन्हें टेप या वेंगर्ट सूची<ref>{{cite journal|last1=Bartholomew-Biggs|first1=Michael| last2=Brown|first2=Steven|last3=Christianson|first3=Bruce|last4=Dixon|first4=Laurence|date=2000|title=एल्गोरिदम का स्वचालित विभेदन|journal=Journal of Computational and Applied Mathematics| volume=124|issue=1–2|pages=171–190| doi=10.1016/S0377-0427(00)00422-2|bibcode=2000JCoAM.124..171B|hdl=2299/3010|hdl-access=free}}</ref> (हालाँकि, वेंगर्ट ने अग्रगामी संचयन प्रकाशित किया, न कि उत्क्रम संचय<ref name="Wengert1964">{{cite journal|author=R.E. Wengert|title=एक सरल स्वचालित व्युत्पन्न मूल्यांकन कार्यक्रम|journal=Comm. ACM|volume=7
उत्क्रम संचयन श्रृंखला नियम को बाहर से अंदर तक, या चित्र 3 में अभिकलनीय ग्राफ की स्थिति में, ऊपर से नीचे तक चंक्रमण करता है। उदाहरण फलन अदिश-मूल्यवान है, और इस प्रकार अवकलज गणना के लिए केवल एक सीड है, और (दो-घटक) प्रवणता की गणना करने के लिए अभिकलनीय ग्राफ के केवल एक स्वीप की आवश्यकता होती है। अग्रगामी संचयन की तुलना में यह केवल [[आधा काम]] है, लेकिन उत्क्रम संचयन के लिए मध्यवर्ती चर {{math|''w''<sub>''i''</sub>}} के भंडारण की आवश्यकता होती है जो उन्हें टेप या वेंगर्ट सूची<ref>{{cite journal|last1=Bartholomew-Biggs|first1=Michael| last2=Brown|first2=Steven|last3=Christianson|first3=Bruce|last4=Dixon|first4=Laurence|date=2000|title=एल्गोरिदम का स्वचालित विभेदन|journal=Journal of Computational and Applied Mathematics| volume=124|issue=1–2|pages=171–190| doi=10.1016/S0377-0427(00)00422-2|bibcode=2000JCoAM.124..171B|hdl=2299/3010|hdl-access=free}}</ref> (हालाँकि, वेंगर्ट ने अग्रगामी संचयन प्रकाशित किया, न कि उत्क्रम संचय<ref name="Wengert1964">{{cite journal|author=R.E. Wengert|title=एक सरल स्वचालित व्युत्पन्न मूल्यांकन कार्यक्रम|journal=Comm. ACM|volume=7
Line 145: Line 145:
===== छद्म कोड =====
===== छद्म कोड =====
उत्क्रम संचयन के लिए दो पास की आवश्यकता होती है, अग्रगामी पास में, फलन का पहले मूल्यांकन किया जाता है और आंशिक परिणाम कैश किए जाते हैं। उत्क्रम पास में, आंशिक अवकलज की गणना की जाती है और पहले से प्राप्त मूल्य को पृष्‍ठ संचरण  किया जाता है। संबंधित विधि कॉल से अपेक्षा की जाती है कि व्यंजक Z को व्युत्पन्न किया जाए और मूल व्यंजक के व्युत्पन्न मूल्य के साथ सीड किया जाए। शीर्ष व्यंजक के लिए, Z, Z के संबंध में व्युत्पन्न, यह 1 है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है और अवकलज व्यंजक में वर्तमान सीड मान जोड़ती  है।<ref name=ssdbm21>{{cite journal|author= Maximilian E. Schüle, Harald Lang, Maximilian Springer, [[Alfons Kemper]], [[Thomas Neumann]], Stephan Günnemann|title=जीपीयू पर एसक्यूएल के साथ इन-डेटाबेस मशीन लर्निंग|journal=33rd International Conference on Scientific and Statistical Database Management|date=2021|doi = 10.1145/3468791.3468840|language=English}}</ref><ref name=dpd>{{cite journal|author= Maximilian E. Schüle, Harald Lang, Maximilian Springer, [[Alfons Kemper]], [[Thomas Neumann]], Stephan Günnemann|title=इन-डेटाबेस मशीन लर्निंग के लिए पुनरावर्ती एसक्यूएल और जीपीयू-समर्थन|journal=Distributed and Parallel Databases|date=2022|doi = 10.1007/s10619-022-07417-7|language=English}}</ref>
उत्क्रम संचयन के लिए दो पास की आवश्यकता होती है, अग्रगामी पास में, फलन का पहले मूल्यांकन किया जाता है और आंशिक परिणाम कैश किए जाते हैं। उत्क्रम पास में, आंशिक अवकलज की गणना की जाती है और पहले से प्राप्त मूल्य को पृष्‍ठ संचरण  किया जाता है। संबंधित विधि कॉल से अपेक्षा की जाती है कि व्यंजक Z को व्युत्पन्न किया जाए और मूल व्यंजक के व्युत्पन्न मूल्य के साथ सीड किया जाए। शीर्ष व्यंजक के लिए, Z, Z के संबंध में व्युत्पन्न, यह 1 है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है और अवकलज व्यंजक में वर्तमान सीड मान जोड़ती  है।<ref name=ssdbm21>{{cite journal|author= Maximilian E. Schüle, Harald Lang, Maximilian Springer, [[Alfons Kemper]], [[Thomas Neumann]], Stephan Günnemann|title=जीपीयू पर एसक्यूएल के साथ इन-डेटाबेस मशीन लर्निंग|journal=33rd International Conference on Scientific and Statistical Database Management|date=2021|doi = 10.1145/3468791.3468840|language=English}}</ref><ref name=dpd>{{cite journal|author= Maximilian E. Schüle, Harald Lang, Maximilian Springer, [[Alfons Kemper]], [[Thomas Neumann]], Stephan Günnemann|title=इन-डेटाबेस मशीन लर्निंग के लिए पुनरावर्ती एसक्यूएल और जीपीयू-समर्थन|journal=Distributed and Parallel Databases|date=2022|doi = 10.1007/s10619-022-07417-7|language=English}}</ref>
   void derive(Expression Z, float seed) {              यदि (Z = X + Y)
   void derive(Expression Z, float seed) {              if (Z = X + Y)
       अवकलज (X, सीड);
       derive(X, seed);
       अवकलज (Y, सीड);
       derive(Y, seed);
   अन्यथा यदि (Z = X - Y)
   else if (Z = X - Y)
       अवकलज (X, सीड);
       derive(X, seed);
       अवकलज(Y,-सीड);
       derive(Y,-seed);
   अन्यथा यदि (Z = X * Y)
   else if (Z = X * Y)
       अवकलज(X,valueOf(X)*seed);
       derive(X,valueOf(X)*seed);
       अवकलज(Y,seed*valueOf(Y));
       derive(Y,seed*valueOf(Y));
   अन्यथा यदि वैरिएबल (जेड) है
   else if वैरिएबल (जेड) है
       आंशिकDerivativeOf(Z) += बीज;                      }
       partialDerivativeOf(Z) += seed;                      }


===== पायथन =====
===== पायथन =====
Line 200: Line 200:
   #include <iostream>                                          #include <string>                                    #include <map>                                    struct Expression {                                float forward=0, backward=0;
   #include <iostream>                                          #include <string>                                    #include <map>                                    struct Expression {                                float forward=0, backward=0;
   virtual float eval(std::map<std::string,float> &vals) = 0;
   virtual float eval(std::map<std::string,float> &vals) = 0;
   virtual void back(float seed) { backward+=seed; };  };                                                struct Plus: public Expression {                    व्यंजक *a, *b;
   virtual void back(float seed) { backward+=seed; };  };                                                struct Plus: public Expression {                    Expression *a, *b;
       Plus(Expression *a, Expression *b): a{a}, b{b} {}
       Plus(Expression *a, Expression *b): a{a}, b{b} {}
       float eval(std::map<std::string,float> &vals) {
       float eval(std::map<std::string,float> &vals) {
Line 211: Line 211:
     a->back(seed);
     a->back(seed);
     b->back(seed);
     b->back(seed);
   }                                                      };                                                struct Mul: public Expression {                      व्यंजक *a, *b;
   }                                                      };                                                struct Mul: public Expression {                      Expression *a, *b;
       Mul(Expression *a, Expression *b): a{a}, b{b} {}    float eval(std::map<std::string,float> &vals) {
       Mul(Expression *a, Expression *b): a{a}, b{b} {}    float eval(std::map<std::string,float> &vals) {
       backward=0;
       backward=0;
Line 241: Line 241:
=== अग्रगामी और उत्क्रम संचयन के अतिरिक्त ===
=== अग्रगामी और उत्क्रम संचयन के अतिरिक्त ===


अग्रगामी और उत्क्रम संचयन श्रृंखला नियम को चंक्रमण करने के केवल दो (चरम) तरीके हैं। अंकगणितीय संक्रियाओं की न्यूनतम संख्या के साथ {{math|''f'' : '''R'''<sup>''n''</sup> → '''R'''<sup>''m''</sup>}} के पूर्ण जैकोबियन की गणना करने की समस्या को इष्टतम जैकोबियन संचयन (ओजेए) समस्या के रूप में जाना जाता है, जो [[एनपी-पूर्ण]] है।।<ref>{{Cite journal|first=Uwe|last=Naumann|journal=Mathematical Programming|volume=112|issue=2|pages=427–441|date=April 2008|doi=10.1007/s10107-006-0042-z|title=इष्टतम जैकोबियन संचय एनपी-पूर्ण है|citeseerx=10.1.1.320.5665|s2cid=30219572}}</ref> इस प्रमाण के केंद्र में यह विचार है कि ग्राफ़ के किनारों को लेबल करने वाले स्थानीय आंशिक भागों के बीच बीजगणितीय निर्भरताएँ उपस्थित हो सकती हैं। विशेष रूप से, दो या दो से अधिक एज लेबल को बराबर के रूप में पहचाना जा सकता है। समस्या की जटिलता अभी भी विवृत है यदि यह मान लिया जाए कि सभी किनारे के लेबल अद्वितीय और बीजगणितीय रूप से स्वतंत्र हैं।
अग्रगामी और उत्क्रम संचयन श्रृंखला नियम को चंक्रमण करने के केवल दो (चरम) तरीके हैं। अंकगणितीय संक्रियाओं की न्यूनतम संख्या के साथ {{math|''f'' : '''R'''<sup>''n''</sup> → '''R'''<sup>''m''</sup>}} के पूर्ण जैकोबियन की गणना करने की समस्या को इष्टतम जैकोबियन संचयन (ओजेए) समस्या के रूप में जाना जाता है, जो [[एनपी-पूर्ण]] है।।<ref>{{Cite journal|first=Uwe|last=Naumann|journal=Mathematical Programming|volume=112|issue=2|pages=427–441|date=April 2008|doi=10.1007/s10107-006-0042-z|title=इष्टतम जैकोबियन संचय एनपी-पूर्ण है|citeseerx=10.1.1.320.5665|s2cid=30219572}}</ref> इस प्रमाण के केंद्र में यह विचार है कि ग्राफ़ के किनारों को लेबल करने वाले स्थानीय आंशिक भागों के बीच बीजगणितीय निर्भरताएँ उपस्थित हो सकती हैं। विशेष रूप से, दो या दो से अधिक एज लेबल को बराबर के रूप में पहचाना जा सकता है। समस्या की जटिलता अभी भी विवृत है if यह मान लिया जाए कि सभी किनारे के लेबल अद्वितीय और बीजगणितीय रूप से स्वतंत्र हैं।


== दोहरी संख्याओं का उपयोग करके स्वचालित अवकलन ==
== दोहरी संख्याओं का उपयोग करके स्वचालित अवकलन ==
Line 256: Line 256:
<math>(1 + y'\varepsilon/y) \cdot (1 - y'\varepsilon/y) = 1</math> का उपयोग करते हुए।
<math>(1 + y'\varepsilon/y) \cdot (1 - y'\varepsilon/y) = 1</math> का उपयोग करते हुए।


अब, इस संवर्धित अंकगणित में बहुपदों की गणना की जा सकती है। यदि<math>P(x) = p_0 + p_1 x + p_2x^2 + \cdots + p_n x^n</math>, तब<math display="block">\begin{align}
अब, इस संवर्धित अंकगणित में बहुपदों की गणना की जा सकती है। if<math>P(x) = p_0 + p_1 x + p_2x^2 + \cdots + p_n x^n</math>, तब<math display="block">\begin{align}
   P(x + x'\varepsilon) &= p_0 + p_1(x + x'\varepsilon) + \cdots + p_n (x + x'\varepsilon)^n \\
   P(x + x'\varepsilon) &= p_0 + p_1(x + x'\varepsilon) + \cdots + p_n (x + x'\varepsilon)^n \\
                       &= p_0 + p_1 x + \cdots + p_n x^n + p_1x'\varepsilon + 2p_2xx'\varepsilon + \cdots + np_n x^{n-1} x'\varepsilon \\
                       &= p_0 + p_1 x + \cdots + p_n x^n + p_1x'\varepsilon + 2p_2xx'\varepsilon + \cdots + np_n x^{n-1} x'\varepsilon \\
Line 287: Line 287:
===सदिश तर्क और फलन  ===
===सदिश तर्क और फलन  ===


दिशात्मक अवकलज संचालक को अपनाकर बहुभिन्नरूपी फलनो को अविभाज्य फलनो  के समान दक्षता और तंत्र के साथ संभाला जा सकता है। अर्थात्, यदि यह  <math>y' = \nabla f(x)\cdot x'</math> गणना करने के लिए पर्याप्त है, तो <math>x' \in \R^n</math> की दिशा में  <math>x \in \R^n</math> पर <math>f:\R^n\to\R^m</math> का दिशात्मक अवकलज <math>y' \in \R^m</math> ऊपर के समान अंकगणित का उपयोग करके<math>(\langle y_1,y'_1\rangle, \ldots, \langle y_m,y'_m\rangle) = f(\langle x_1,x'_1\rangle, \ldots, \langle x_n,x'_n\rangle)</math> के रूप में गणना की जा सकती है। यदि के <math>\nabla f</math> सभी अवयव वांछित हों, तो <math>n</math> फलन मूल्यांकन की आवश्यकता होगी। ध्यान दें कि कई अनुकूलन अनुप्रयोगों में, दिशात्मक अवकलज वास्तव में पर्याप्त है।
दिशात्मक अवकलज संचालक को अपनाकर बहुभिन्नरूपी फलनो को अविभाज्य फलनो  के समान दक्षता और तंत्र के साथ संभाला जा सकता है। अर्थात्, if यह  <math>y' = \nabla f(x)\cdot x'</math> गणना करने के लिए पर्याप्त है, तो <math>x' \in \R^n</math> की दिशा में  <math>x \in \R^n</math> पर <math>f:\R^n\to\R^m</math> का दिशात्मक अवकलज <math>y' \in \R^m</math> ऊपर के समान अंकगणित का उपयोग करके<math>(\langle y_1,y'_1\rangle, \ldots, \langle y_m,y'_m\rangle) = f(\langle x_1,x'_1\rangle, \ldots, \langle x_n,x'_n\rangle)</math> के रूप में गणना की जा सकती है। if के <math>\nabla f</math> सभी अवयव वांछित हों, तो <math>n</math> फलन मूल्यांकन की आवश्यकता होगी। ध्यान दें कि कई अनुकूलन अनुप्रयोगों में, दिशात्मक अवकलज वास्तव में पर्याप्त है।


===उच्च क्रम और कई चर===
===उच्च क्रम और कई चर===
Line 314: Line 314:
== संचालक अतिभारक और स्रोत कोड परिवर्तन ==
== संचालक अतिभारक और स्रोत कोड परिवर्तन ==


अतिभारित संचालको का उपयोग मूल्याकंन ग्राफ़ निकालने के लिए किया जा सकता है, जिसके बाद कार्य अवधि पर प्रारंभिक फलन के एडी-संस्करण की स्वचालित पीढ़ी होती है। प्रतिष्ठित ओओ एएडी के विपरीत, ऐसा एडी-फलन एक पुनरावृत्ति से अगले में नहीं परिवर्तित होता है। इसलिए प्रति एक्सi प्रतिदर्श में कोई ओओ या टेप व्याख्या कार्य अवधि शिरोपरि है।
अतिभारित संचालको का उपयोग मूल्याकंन ग्राफ़ निकालने के लिए किया जा सकता है, जिसके बाद कार्य अवधि पर प्रारंभिक फलन के एडी-संस्करण की स्वचालित पीढ़ी होती है। प्रतिष्ठित ओओ एएडी के विपरीत, ऐसा एडी-फलन एक return से अगले में नहीं परिवर्तित होता है। इसलिए प्रति एक्सi प्रतिदर्श में कोई ओओ या टेप व्याख्या कार्य अवधि शिरोपरि है।


कार्य अवधि पर एडी-फलन उत्पन्न होने के साथ, इसे प्रोग्राम की वर्तमान स्थिति को ध्यान में रखने और कुछ मानों की पूर्व-गणना करने के लिए अनुकूलित किया जा सकता है। इसके अलावा, इसे उपयोगकर्ता डेटा के 4(8)-दोगुने टुकड़ों (एवीएक्स2\एवीएक्स512 गति x4-x8) को संसाधित करने के लिए मूल सीपीयू वैश्वीकरण का लगातार उपयोग करने के तरीके से उत्पन्न किया जा सकता है। बहु सूत्रण को ध्यान में रखते हुए, इस तरह के दृष्टिकोण से पारंपरिक एएडी उपकरण की तुलना में ऑर्डर 8 × #कोर्स का अंतिम त्वरण हो सकता है। एक संदर्भ कार्यान्वयन गिटहब पर उपलब्ध है।<ref>{{Cite web|url=https://github.com/matlogica/aadc-prototype|title=एएडीसी प्रोटोटाइप लाइब्रेरी|date=June 22, 2022|via=GitHub}}</ref>
कार्य अवधि पर एडी-फलन उत्पन्न होने के साथ, इसे प्रोग्राम की वर्तमान स्थिति को ध्यान में रखने और कुछ मानों की पूर्व-गणना करने के लिए अनुकूलित किया जा सकता है। इसके अलावा, इसे उपयोगकर्ता डेटा के 4(8)-दोगुने टुकड़ों (एवीएक्स2\एवीएक्स512 गति x4-x8) को संसाधित करने के लिए मूल सीपीयू वैश्वीकरण का लगातार उपयोग करने के तरीके से उत्पन्न किया जा सकता है। बहु सूत्रण को ध्यान में रखते हुए, इस तरह के दृष्टिकोण से पारंपरिक एएडी उपकरण की तुलना में ऑर्डर 8 × #कोर्स का अंतिम त्वरण हो सकता है। एक संदर्भ कार्यान्वयन गिटहब पर उपलब्ध है।<ref>{{Cite web|url=https://github.com/matlogica/aadc-prototype|title=एएडीसी प्रोटोटाइप लाइब्रेरी|date=June 22, 2022|via=GitHub}}</ref>

Revision as of 08:31, 26 July 2023

गणित और कंप्यूटर बीजगणित में, स्वचालित अवकलन (स्व-अवकलन, ऑटोडिफ़, या एआडी), जिसे कलनविधीय अवकलन तथा अभिकलनीय अवकलन भी कहा जाता है,[1][2] और यह कंप्यूटर प्रोग्राम द्वारा निर्दिष्ट फलन के आंशिक अवकलज का मूल्यांकन करने के लिए तकनीकों का एक समुच्चय है।

स्वचालित अवकलन इस तथ्य का फायदा उठाता है कि प्रत्येक कंप्यूटर प्रोग्राम, चाहे कितना भी जटिल क्यों न हो, प्राथमिक अंकगणितीय संचालन (जोड़, घटाव, गुणा, भाग, आदि) और प्राथमिक फलनो (ऍक्स्प, लॉग, साइन, कॉस, आदि) के अनुक्रम को निष्पादित करता है। इन परिचालनों में श्रृंखला नियम को बार-बार लागू करने से, यादृच्छिक रूप से क्रम के आंशिक अवकलज की गणना स्वचालित रूप से, सटीकता से काम करने के लिए की जा सकती है, और मूल प्रोग्राम की तुलना में अधिक अंकगणितीय संचालन के एक छोटे स्थिर कारक का उपयोग किया जा सकता है।

अन्य अवकलन विधियों से अंतर

चित्र 1, स्वचालित अवकलन प्रतीकात्मक अवकलन से कैसे संबंधित है

स्वचालित अवकलन प्रतीकात्मक अवकलन और संख्यात्मक अवकलन से भिन्न है। प्रतीकात्मक अवकलन से कंप्यूटर प्रोग्राम को एकल गणितीय व्यंजक में परिवर्तित करने में कठिनाई का सामना करना पड़ता है और इससे अकुशल कोड हो सकता है। संख्यात्मक अवकलन (परिमित अंतर की विधि) विवेकीकरण प्रक्रिया और निरस्तीकरण में निकटन त्रुटियां प्रस्तुत कर सकता है। इन दोनों चिरप्रतिष्ठित विधियों में उच्च अवकलज की गणना करने में समस्याएं होती हैं, जहां जटिलता और त्रुटियां बढ़ जाती हैं। अंत में, ये दोनों चिरप्रतिष्ठित विधियां कई निविष्ट के संबंध में किसी फलन के आंशिक अवकलज की गणना करने में धीमी हैं, जैसा कि प्रवणता-आधारित इष्टमीकरण कलन विधि के लिए आवश्यक है। स्वचालित अवकलन इन सभी समस्याओं का समाधान करता है।

अग्रगामी और उत्क्रम संचयन

समग्र फलनों के आंशिक अवकलजों का श्रृंखला नियम

स्वचालित अवकलन के लिए मूल, संयुक्त फलनो के आंशिक अवकलज के श्रृंखला नियम द्वारा प्रदान किए गए अंतर का अपघटन है। सरल संयोजन

के लिए श्रृंखला नियम
देता है

दो प्रकार के स्वचालित अवकलन

आमतौर पर, स्वचालित अवकलन के दो अलग-अलग तरीके प्रस्तुत किए जाते हैं।

  • अग्रगामी संचयन (जिसे समानयन, अग्रगामी मोड या स्पर्शी मोड भी कहा जाता है)
  • उत्क्रम संचयन (जिसे अधोशीर्ष, उत्क्रम मोड या सहखंडज मोड भी कहा जाता है)

अग्रगामी संचयन निर्दिष्ट करता है कि कोई व्यक्ति श्रृंखला नियम को अंदर से (अर्थात, पहले की गणना करें और फिर की तथा अंत में की गणना करें) बाहर तक चंक्रमण करता है, जबकि उत्क्रम संचयन में बाहर से अंदर (पहले की गणना करें और फिर की और अंत में की गणना करें) तक चंक्रमण करता है।

  • अग्रगामी संचयन पुनरावर्ती संबंध की गणना करता है, के साथ , और,
  • उत्क्रम संचयन पुनरावर्ती संबंध की गणना करता है, के साथ

आंशिक अवकलज का मूल्य, जिसे सीड कहा जाता है, अग्रगामी या पश्चगामी प्रसारित होता है और प्रारंभ में या होता है। अग्रगामी संचयन फलन का मूल्यांकन करता है और एक पास में एक स्वतंत्र चर के संबंध में अवकलज की गणना करता है। प्रत्येक स्वतंत्र चर के लिए एक अलग पास आवश्यक है जिसमें उस स्वतंत्र चर के संबंध में अवकलज को एक () और अन्य सभी को शून्य () पर निर्धारित किया जाता है। इसके उत्क्रम, उत्क्रम संचयन के लिए आंशिक अवकलज के लिए मूल्यांकन किए गए आंशिक फलनो की आवश्यकता होती है। इसलिए उत्क्रम संचयन पहले फलन का मूल्यांकन करता है और एक अतिरिक्त पास में सभी स्वतंत्र चर के संबंध में अवकलज की गणना करता है।

इन दोनों प्रकारों में से किसका उपयोग किया जाना चाहिए यह स्वीप गणना पर निर्भर करता है। एक स्वीप का अभिकलनीय जटिलता मूल कोड की जटिलता के समानुपाती होती है।

  • nm के साथ फलन f : RnRm के लिए उत्क्रम संचयन की तुलना में अग्रगामी संचयन अधिक कुशल है क्योंकि उत्क्रम संचयन के लिए m स्वीप की तुलना में केवल n स्वीप आवश्यक हैं।
  • फलन f : RnRm के लिए nm के साथ अग्रगामी संचयन की तुलना में उत्क्रम संचयन अधिक कुशल है क्योंकि अग्रगामी संचयन के लिए n स्वीप की तुलना में केवल m स्वीप आवश्यक है।

बहुपरतीय परसेप्ट्रॉन में त्रुटियों की पश्चसंचरण, यंत्र अधिगम में उपयोग की जाने वाली तकनीक, उत्क्रम संचयन की एक विशेष स्थिति है।[2]

अग्रगामी संचयन की शुरुआत 1964 में आर.ई. वेंगर्ट द्वारा की गई थी।।[3] एंड्रियास ग्रिवैंक के अनुसार, 1960 के दशक के उत्तरार्ध से उत्क्रम संचयन का सुझाव दिया गया है, लेकिन आविष्कारक अज्ञात है।[4] सेप्पो लिन्नैनमा ने 1976 में उत्क्रम संचयन प्रकाशित किया।[5]

अग्रगामी संचयन

अग्रगामी संचयन

अग्रगामी संचयन एडी में, व्यक्ति पहले स्वतंत्र चर को निर्धारित करता है जिसके संबंध में अवकलन किया जाता है और प्रत्येक उप-व्यंजक के अवकलज की पुनरावर्ती गणना करता है। कलम और कागज की गणना में, इसमें श्रृंखला नियम में आंतरिक फलनो के अवकलज को बार-बार प्रतिस्थापित करना सम्मिलित है,

इसे जैकोबियन के आव्यूह गुणन के रूप में कई चर के लिए सामान्यीकृत किया जा सकता है।

उत्क्रम संचयन की तुलना में, अग्रगामी संचयन स्वाभाविक रूप से लागू करना आसान है क्योंकि अवकलज सूचना का प्रवाह मूल्यांकन के क्रम के साथ मेल खाता है। प्रत्येक चर को इसके अवकलज (संख्यात्मक मान के रूप में संग्रहीत, प्रतीकात्मक व्यंजक नहीं),

के साथ संवर्धित किया गया है ,जैसा कि बिंदु द्वारा दर्शाया गया है। फिर मूल्यांकन चरणों के साथ अवकलज की गणना की जाती है और श्रृंखला नियम के माध्यम से अन्य अवकलज के साथ जोड़ा जाता है। श्रृंखला नियम का उपयोग करते हुए, if के पास अभिकलनीय ग्राफ़ में पूर्ववर्ती हैं, तो

चित्र 2, अभिकलनीय ग्राफ़ के साथ अग्रगामी संचयन का उदाहरण

उदाहरण के तौर पर, फलन पर विचार करें,

स्पष्टता के लिए, व्यक्तिगत उप-व्यंजको को चर के साथ वर्गीकृत किया गया है .

जिस स्वतंत्र चर का विभेदीकरण किया जाता है उसका चयन सीड मूल्यों 1 और 2 को प्रभावित करता है। x1 के संबंध में इस फलन के अवकलज में रुचि को देखते हुए, सीड मान को इस पर निर्धारित किया जाना चाहिए,

सीड मान निर्धारित होने के साथ, मान दिखाए गए अनुसार श्रृंखला नियम का उपयोग करके प्रसारित होते हैं। चित्र 2 एक अभिकलनीय ग्राफ़ के रूप में इस प्रक्रिया का सचित्र चित्रण दिखाता है।

मूल्य की गणना करने के लिए संचालन अवकलज की गणना करने के लिए संचालन
(seed)
(seed)

इस उदाहरण फलन की प्रवणता की गणना करने के लिए, जिसके लिए न केवल बल्कि की भी आवश्यकता होती है, सीड मान का उपयोग करके अभिकलनीय ग्राफ़ पर एक अतिरिक्त स्वीप किया जाता है।

कार्यान्वयन

छद्म कोड

अग्रगामी संचयन एक पास में, फलन और अवकलज (लेकिन केवल एक स्वतंत्र चर के लिए) की गणना करता है। संबंधित विधि कॉल एक चर V के संबंध में व्यंजक Z को प्राप्त करने की अपेक्षा करती है। विधि मूल्यांकन किए गए फलन और इसके अवकलन की एक जोड़ी की return है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है। if इस चर के संबंध में अवकलज का अनुरोध किया जाता है, तो इसका अवकलज 1, 0 होगा else। फिर आंशिक फलन के साथ-साथ आंशिक अवकलज का मूल्यांकन किया जाता है।[6]

tuple<float,float>eval(Expression Z, Expression V) {  if isVariable (Z)
     if (Z=V) return {valueOf(Z),1};
     else return {valueOf(Z),0};
  else if (Z = X + Y)
     {x,x'} = eval(X,V);
     {y,y'} = eval(Y,V);
     return {x+y, x'+y'};
  else if (Z = X - Y)
     {x,x'} = eval(X,V);
     {y,y'} = eval(Y,V);
     return {x-y, x'-y'};
  else if (Z = X * Y)
     {x,x'} = eval(X,V);
     {y,y'} = eval(Y,V);
     return {x*y, x'*y+x*y'};                                              
सी++
#include <iostream>
#include <string>
  #include <map>
     typedef struct dual { float v,d; } dual;
    struct Expression {                                 virtual dual eval(std::map<std::string,float>         &vals, Expression *v) { return {0,0}; };               };                                                   struct Plus: public Expression {                 Expression *a, *b;                         Plus(Expression *a, Expression *b): a{a}, b{b} {}      dual eval(std::map<std::string,float> &vals, Expression *v) {                                                dual x=a->eval(vals,v);                              dual y=b->eval(vals,v);                            return {x.v+y.v, x.d+y.d};                                                                     }                                                     };                                                struct Var: public Expression {                       std::string s;                                            Var(std::string s) : s{s} {}                            dual eval(std::map<std::string,float> &vals,  Expression *v) {                                                     return {vals[s], this==v?1.0f:0.0f};                     }                                                      };                                                   int main (){                             std,,map<std,,string,float> dict;
  dict.insert(std,,pair<std,,string,int>( x ,1));
  dict.insert(std,,pair<std,,string,int>( y ,-3));
  dict.insert(std,,pair<std,,string,int>( z ,4));
  Var x( x ), y( y ), z( z );
  Mul m1(&x,&z); Mul m2(&y,&z); Plus p(&m1,&m2); // x*z+y*z
  std,,cout << x, << p.eval(dict,&x).d << , << y, << p.eval(dict,&y).d << , << z, << p. eval(dict,&z).d << std,,endl;
  return 0;

उत्क्रम संचयन

उत्क्रम संचयन एडी में, अवकलित किए जाने वाले आश्रित चर को तय किया जाता है और अवकलज की गणना प्रत्येक उप-व्यंजक के संबंध में पुनरावर्ती रूप से की जाती है। कलम और कागज की गणना में, बाहरी फलनो के अवकलज को श्रृंखला नियम में बार-बार प्रतिस्थापित किया जाता है,

उत्क्रम संचयन में, ब्याज की मात्रा सहायक होती है, जिसे एक बार से दर्शाया जाता है, यह उपव्यंजक के संबंध में चुने गए आश्रित चर का अवकलज है,
श्रृंखला नियम का उपयोग करते हुए, if के पासअभिकलनीय ग्राफ़ में परवर्ती हैं, तो

उत्क्रम संचयन श्रृंखला नियम को बाहर से अंदर तक, या चित्र 3 में अभिकलनीय ग्राफ की स्थिति में, ऊपर से नीचे तक चंक्रमण करता है। उदाहरण फलन अदिश-मूल्यवान है, और इस प्रकार अवकलज गणना के लिए केवल एक सीड है, और (दो-घटक) प्रवणता की गणना करने के लिए अभिकलनीय ग्राफ के केवल एक स्वीप की आवश्यकता होती है। अग्रगामी संचयन की तुलना में यह केवल आधा काम है, लेकिन उत्क्रम संचयन के लिए मध्यवर्ती चर wi के भंडारण की आवश्यकता होती है जो उन्हें टेप या वेंगर्ट सूची[7] (हालाँकि, वेंगर्ट ने अग्रगामी संचयन प्रकाशित किया, न कि उत्क्रम संचय[3]) के रूप में ज्ञात डेटा संरचना में उत्पन्न करते हैं, जो अभिकलनीय ग्राफ़ बड़ा होने पर महत्वपूर्ण मेमोरी का उपभोग कर सकता है। मध्यवर्ती चरों के केवल एक उपसमूह को संग्रहीत करके और फिर मूल्यांकन को दोहराकर आवश्यक कार्य चरों का पुनर्निर्माण करके इसे कुछ हद तक कम किया जा सकता है, एक तकनीक जिसे पुनर्भौतिकीकरण के रूप में जाना जाता है। जाँच बिन्दु का उपयोग मध्यस्थ अवस्थाओ को बचाने के लिए भी किया जाता है।

चित्र 3, अभिकलनीय ग्राफ़ के साथ उत्क्रम संचयन का उदाहरण

उत्क्रम संचयन का उपयोग करके अवकलज की गणना करने के संचालन को नीचे दी गई तालिका में दिखाया गया है (उत्क्रमित क्रम पर ध्यान दें),

अवकलज की गणना करने के लिए संचालन

किसी गणना के डेटा प्रवाह ग्राफ़ को उसकी मूल गणना की प्रवणता की गणना करने के लिए प्रकलित किया जा सकता है। यह प्रत्येक प्रारंभिक नोड के लिए एक सहखंडज नोड जोड़कर किया जाता है, जो सहखंडज किनारों से जुड़ा होता है जो कि प्रारंभिक किनारों के समानांतर होता है लेकिन उत्क्रम दिशा में बहता है। निकटवर्ती ग्राफ में नोड्स प्रारंभिक में नोड्स द्वारा गणना किए गए फलनो के अवकलज द्वारा गुणन का प्रतिनिधित्व करते हैं। उदाहरण के लिए, मूल में जोड़ के कारण जोड़ में बहिर्गमांक हो जाता है, सहखंडज में बहिर्गमांक के कारण जोड़ में वृद्धि होती है,[lower-alpha 1] प्रारंभिक कारणों में एक एकल फलन y = f(x), सहखंडज में = ȳ f′(x) आदि होते है।

कार्यान्वयन

छद्म कोड

उत्क्रम संचयन के लिए दो पास की आवश्यकता होती है, अग्रगामी पास में, फलन का पहले मूल्यांकन किया जाता है और आंशिक परिणाम कैश किए जाते हैं। उत्क्रम पास में, आंशिक अवकलज की गणना की जाती है और पहले से प्राप्त मूल्य को पृष्‍ठ संचरण किया जाता है। संबंधित विधि कॉल से अपेक्षा की जाती है कि व्यंजक Z को व्युत्पन्न किया जाए और मूल व्यंजक के व्युत्पन्न मूल्य के साथ सीड किया जाए। शीर्ष व्यंजक के लिए, Z, Z के संबंध में व्युत्पन्न, यह 1 है। यह विधि एक चर तक पहुंचने तक व्यंजक वृक्ष को पुनरावर्ती रूप से चंक्रमण करती है और अवकलज व्यंजक में वर्तमान सीड मान जोड़ती है।[8][9]

 void derive(Expression Z, float seed) {              if (Z = X + Y)
     derive(X, seed);
     derive(Y, seed);
  else if (Z = X - Y)
     derive(X, seed);
     derive(Y,-seed);
  else if (Z = X * Y)
     derive(X,valueOf(X)*seed);
     derive(Y,seed*valueOf(Y));
  else if वैरिएबल (जेड) है
     partialDerivativeOf(Z) += seed;                       }
पायथन

बिना टेप के पायथन में कार्यान्वयन।

import math

class Var:
    def __init__(self, value, children=None):
        self.value = value
        self.children = children or []
        self.grad = 0

    def __add__(self, other):
        return Var(self.value + other.value, [(1, self), (1, other)])

    def __mul__(self, other):
        return Var(self.value * other.value, [(other.value, self), (self.value, other)])

    def sin(self):
        return Var(math.sin(self.value), [(math.cos(self.value), self)])

    def calc_grad(self, grad=1):
        self.grad += grad
        for coef, child in self.children:
            child.calc_grad(grad * coef)

# Example: f(x, y) = x * y + sin(x)
x = Var(2)
y = Var(3)
f = x * y + x.sin()

# Calculation of partial derivatives
f.calc_grad()

print("f =", f.value)
print("∂f/∂x =", x.grad)
print("∂f/∂y =", y.grad)


सी++
  #include <iostream>                                           #include <string>                                     #include <map>                                    struct Expression {                                float forward=0, backward=0;
  virtual float eval(std::map<std::string,float> &vals) = 0;
  virtual void back(float seed) { backward+=seed; };  };                                                 struct Plus: public Expression {                    Expression *a, *b;
     Plus(Expression *a, Expression *b): a{a}, b{b} {}
     float eval(std::map<std::string,float> &vals) {
     backward=0;
     forward=a->eval(vals); forward+=b->eval(vals);
     return forward;
  }
    void back(float seed) {
    Expression::back(seed);
    a->back(seed);
    b->back(seed);
  }                                                      };                                                 struct Mul: public Expression {                      Expression *a, *b;
     Mul(Expression *a, Expression *b): a{a}, b{b} {}     float eval(std::map<std::string,float> &vals) {
     backward=0;
     forward=a->eval(vals); forward*=b->eval(vals);
           return forward;
  }
   void back(float seed) {
     Expression::back(seed);
    a->back(seed * b->forward);
     b->back(seed * a->forward);
  }                                                        };                                                     struct Var: public Expression {                     std::string s;
  Var(std,,string s)), s{s} {}
    float eval(std::map<std::string,float> &vals) {
      forward=vals[s];
         backward=0;
      return forward;
  }
  void back(float seed) {
      Expression::back(seed);
     std::cout << s << ": " << backward << ", ";
  }                                                   };                                                     int main (){                     std,,map<std,,string,float> dict;
  dict.insert(std,,pair<std,,string,int>( x ,1));
  dict.insert(std,,pair<std,,string,int>( y ,-3));
  dict.insert(std,,pair<std,,string,int>( z ,4));
  Var x( x ), y( y ), z( z ); Mul m1(&x,&z); Mul m2(&y,&z); Plus p(&m1,&m2); // x*z+y*z
  std,,cout << p.eval(dict) << std,,endl;
  p.back(1); std,,cout << std,,endl;
  return 0;                                                 }

अग्रगामी और उत्क्रम संचयन के अतिरिक्त

अग्रगामी और उत्क्रम संचयन श्रृंखला नियम को चंक्रमण करने के केवल दो (चरम) तरीके हैं। अंकगणितीय संक्रियाओं की न्यूनतम संख्या के साथ f : RnRm के पूर्ण जैकोबियन की गणना करने की समस्या को इष्टतम जैकोबियन संचयन (ओजेए) समस्या के रूप में जाना जाता है, जो एनपी-पूर्ण है।।[10] इस प्रमाण के केंद्र में यह विचार है कि ग्राफ़ के किनारों को लेबल करने वाले स्थानीय आंशिक भागों के बीच बीजगणितीय निर्भरताएँ उपस्थित हो सकती हैं। विशेष रूप से, दो या दो से अधिक एज लेबल को बराबर के रूप में पहचाना जा सकता है। समस्या की जटिलता अभी भी विवृत है if यह मान लिया जाए कि सभी किनारे के लेबल अद्वितीय और बीजगणितीय रूप से स्वतंत्र हैं।

दोहरी संख्याओं का उपयोग करके स्वचालित अवकलन

वास्तविक संख्याओं के वास्तविक संख्याओं के बीजगणित को बढ़ाकर और एक नया अंकगणित प्राप्त करके अग्रगामी मोड स्वचालित अवकलन पूरा किया जाता है। संख्या पर किसी फलन के अवकलज का प्रतिनिधित्व करने के लिए प्रत्येक संख्या में एक अतिरिक्त घटक जोड़ा जाता है, और सभी अंकगणितीय संचालको को संवर्धित बीजगणित के लिए विस्तारित किया जाता है। संवर्धित बीजगणित दोहरी संख्याओं का बीजगणित है।

प्रत्येक संख्या को संख्या से बदलें, जहाँ एक वास्तविक संख्या है, लेकिन गुण के साथ एक अमूर्त संख्या है (एक अतिसूक्ष्म, सहज अतिसूक्ष्म विश्लेषण देखें)। इसके प्रयोग से ही नियमित अंकगणित मिलता है

का उपयोग करते हुए।

अब, इस संवर्धित अंकगणित में बहुपदों की गणना की जा सकती है। if, तब


जहां अपने पहले तर्क के संबंध में के अवकलज को दर्शाता है, और , जिसे सीड कहा जाता है, उसको स्वेच्छ रूप से चुना जा सकता है।

नए अंकगणित में क्रमित जोड़े, लिखे तत्व, पहले घटक पर सामान्य अंकगणित और दूसरे घटक पर प्रथम क्रम अवकलन अंकगणित के साथ सम्मिलित हैं, जैसा कि ऊपर वर्णित है। बहुपदों पर उपरोक्त परिणामों को विश्लेषणात्मक फलनो तक विस्तारित करने से बुनियादी अंकगणित और नए अंकगणित के लिए कुछ मानक फलनो की एक सूची मिलती है,