C ++ वैज्ञानिक कोड में कई स्थिरांक, चर से निपटने के लिए सर्वोत्तम अभ्यास


17

मैं प्रवाह में मौजूद जैविक पदार्थों के साथ द्रव प्रवाह का अनुकरण करने के लिए एक कोड विकसित कर रहा हूं। इसमें कुछ अतिरिक्त जैविक मॉडल के युग्मित मानक नवियर-स्टोक्स समीकरण शामिल हैं। कई पैरामीटर / स्थिरांक हैं।

मैंने प्रमुख संगणनाओं को संभालने के लिए कार्य लिखे हैं, लेकिन एक समस्या जो मुझे हो रही है वह है बड़ी संख्या में स्थिरांक / पैरामीटर जो इन संगणनाओं पर निर्भर करते हैं। एक समारोह में 10-20 तर्क पारित करना बोझिल लगता है।

एक विकल्प यह है कि सभी स्थिरांक को वैश्विक चर बना दिया जाए, लेकिन मुझे पता है कि यह C ++ में है।

किसी फ़ंक्शन को कई इनपुट से निपटने का मानक तरीका क्या है? क्या मुझे एक ढांचा बनाना चाहिए और उसके बजाय पास करना चाहिए?

धन्यवाद


7
यदि यह संभव है, तो कॉन्स्टेक्स के उपयोग से संकलन समय पर स्थिरांक का मूल्यांकन करने का प्रयास करें। मैं इनमें से अधिकांश को एक अलग हेडर फ़ाइल में शामिल करने की कोशिश करता हूं। चरों के लिए, मैंने पाया है कि एक अलग वर्ग के लाभ हैं, लेकिन संभावित रूप से अधिक बग की कीमत पर क्योंकि आपको फ़ंक्शन में पास होने से पहले वर्ग को इनिशियलाइज़ करना है।
बिस्वजीत बनर्जी

3
यह किसी प्रकार के कोड नमूने के बिना ठीक से उत्तर देना कठिन है। क्या मुझे एक ढांचा बनाना चाहिए और उसके बजाय पास करना चाहिए? सामान्य तौर पर, हाँ, यह बिल्कुल सामान्य तरीका है। मापदंडों / स्थिरांक को उनके अर्थ द्वारा समूहित करें।
किरिल

1
"एक विकल्प यह है कि सभी स्थिरांक को वैश्विक चर बना दिया जाए, लेकिन मुझे पता है कि यह C ++ में भरा हुआ है" क्या यह है?
मोनिका

1
क्या वे वास्तव में, वास्तव में स्थिर हैं? यदि आप अपने मॉडल को एक अलग डोमेन में लागू करना चाहते हैं तो क्या होगा? मैं उन्हें थोड़ी कक्षा में रखने की सलाह दूंगा। वह कम से कम आपको भविष्य में थोड़ा सा लचीलापन देता है
एंड्रे

@ एंड्रे उनमें से ज्यादातर एक पैरामीटर फ़ाइल के माध्यम से उपयोगकर्ता-नियंत्रित होते हैं, यही कारण है कि मैं इस बात से सहमत हूं कि वर्ग समाधान सबसे अच्छा है।
EternusVia

जवाबों:


13

यदि आपके पास स्थिरांक हैं जो रन से पहले नहीं बदलेंगे, तो उन्हें हेडर फ़ाइल में घोषित करें:

//constants.hpp
#ifndef PROJECT_NAME_constants_hpp
#define PROJECT_NAME_constants_hpp
namespace constants {
  constexpr double G        = 6.67408e-11;
  constexpr double M_EARTH  = 5.972e24;
  constexpr double GM_EARTH = G*M_EARTH; 
}
#endif

//main.cpp
using namespace constants;
auto f_earth = GM_EARTH*m/r/r;  //Good
auto f_earth = G*M_EARTH*m/r/r; //Also good: compiler probably does math here too

आप ऐसा क्यों करना चाहते हैं इसका कारण यह है कि यह कंपाइलर को रन-टाइम से पहले निरंतर मूल्यों की गणना करने की अनुमति देता है, जो कि आपके पास बहुत सारे होने पर अच्छा है।

आप मानों को पास करने के लिए एक साधारण वर्ग का भी उपयोग कर सकते हैं:

class Params {
 public:
  double a,b,c,d;
  Params(std::string config_file_name){
    //Load configuration here
  }
};

void Foo(const Params &params) {
  ...
}

int main(int argc, char **argv){
  Params params(argv[1]);
  Foo(params);
}

सभी महान जवाब लेकिन वर्ग-समाधान मेरी स्थिति के लिए सबसे अच्छा काम करता है।
EternusVia

8
यदि आप चर को वैश्विक बनाते constexprहैं, तो कम से कम उन्हें संलग्न करें namespaceताकि वे किसी अन्य वैश्विक प्रतीकों पर कदम न रखें। नामक वैश्विक वैरिएबल का उपयोग करना Gकेवल परेशानी का आह्वान है।
वोल्फगैंग बंगर्थ

1
आप क्यों नेतृत्व करते हैं _ के साथ गार्ड शामिल हैं? आपको कभी भी कुछ भी नहीं लिखना चाहिए, जो _ से शुरू होता है, आप संकलक के साथ टक्कर का जोखिम उठाते हैं। आपको कुछ ऐसा करना चाहिए ifndef PROJECT_NAME_FILE_NAME_EXTENSION। इसके अलावा, सुनिश्चित नहीं है कि आपने स्थिरांक क्यों बनाए, लेकिन आपके गार्ड मैक्रोज़ शामिल नहीं हैं। आप आम तौर पर सभी मैक्रोज़ को भुनाना चाहते हैं, खासकर क्योंकि वे सैनिटरी नहीं हैं। स्थिरांक के लिए पूंजीकरण सामान्य रूप से मायने नहीं रखता है । Gयह ठीक है क्योंकि इसका SI, लेकिन mass_earth अधिक उपयुक्त है, और इसे वैश्विक नाम देने के लिए एक नामस्थान के साथ योग्य होना चाहिए constants::mass_earth
whn

12

एक और विकल्प जो आपके विचार की ट्रेन के अनुरूप हो सकता है, वह है ठीक से समूह स्थिरांक के लिए एक नाम स्थान (या नेस्टेड नामस्थान) का उपयोग करना। एक उदाहरण हो सकता है:

namespace constants {
   namespace earth {
      constexpr double G = 6.67408e-11;
      constexpr double Mass_Earth = 5.972e24;
      constexpr double GM = G*Mass_Earth;
   }// constant properties about Earth

   namespace fluid {
      constexpr double density = 0.999; // g/cm^3
      constexpr double dyn_viscosity = 1.6735; //mPa * s
   }// constants about fluid at 2C

   // ... 

} // end namespace for constants

उपरोक्त तकनीक का उपयोग करते हुए, आप कुछ वांछित फ़ाइलों और नामस्थानों के संदर्भ स्थिरांक को स्थानीय बना सकते हैं, जिससे उन्हें कुछ समान लाभों को प्राप्त करते हुए वैश्विक चर की तुलना में अधिक नियंत्रित किया जा सकता है। जब आप स्थिरांक का उपयोग करते हैं, तो यह करना जितना आसान होता है:

constexpr double G_times_2 = 2.0*constants::earth::G;

यदि आप नेस्टेड नेमस्पेस की लंबी श्रृंखला को नापसंद करते हैं, तो आप हमेशा किसी चीज़ का नाम छोटा करके उपयोग कर सकते हैं:

namespace const_earth = constants::earth;
constexpr double G_times_2 = 2.0*const_earth::G;

2
यह एक दृष्टिकोण है, जिसके बाद OpenFOAM है , OpenFOAM के स्रोत कोड का एक यादृच्छिक उदाहरण देखें । OpenFOAM C ++ कोड लाइब्रेरी है जो परिमित मात्रा पद्धति को लागू करता है, जिसका उपयोग द्रव गतिकी में व्यापक रूप से किया जाता है।
दोहन ​​जो

1

एक तरीका यह है कि मैं सिंगलटन का उपयोग करता हूं।

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


चेतावनी: मैंने कभी-कभी सिंगल-थ्रेड्स को बहु-थ्रेडेड कोड में एक्सेस किया है। तो आप अपने प्रोफाइलिंग चरण के हिस्से के रूप में इस पर जांच करना चाहते हैं।
रिचर्ड

मैं निश्चित रूप से उन्हें एक सिंगलटन में नहीं डालूंगा ... व्यवहार में उन स्थिरांक भविष्य में बदल जाएंगे जब (नहीं तो) आप एक अलग डोमेन में अपना मॉडल लागू करते हैं। उन्हें एक सिंगलटन होने के बाद विभिन्न मापदंडों के साथ परीक्षण करना बहुत मुश्किल हो जाता है।
आंद्रे

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

एकल, शायद ही कभी, एक अच्छा विचार है। निर्भरता इंजेक्शन एक बहुत क्लीनर और अधिक लचीला समाधान है। हालाँकि, केवल स्थिरांक के साथ, मैं कहूँगा कि उन्हें लगातार कहीं हेडर में रखें।
मास्को
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.