2012-04-11 10 views
16

मैं लैपैक और सी ++/फोरट्रान इंटरफेसिंग के साथ शुरुआत कर रहा हूं। मैक ओएस-एक्स शेर पर LAPACK/BLAS का उपयोग करके मुझे रैखिक समीकरणों और eigenvalues ​​समस्याओं को हल करने की आवश्यकता है। ओएस-एक्स शेर अनुकूलित बीएलएएस और लैपैक पुस्तकालयों (इन/यूएसआर/lib) प्रदान करता है और मैं इन पुस्तकालयों को नेटलिब से डाउनलोड करने के बजाय जोड़ रहा हूं।एलएपीएक्स को समझना सी ++ में एक साधारण उदाहरण के साथ

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

चलें कहते हैं कि हम निम्न रेखीय प्रणाली को हल करना चाहते:

x + y = 2

एक्स - y = 0

समाधान है (एक्स, वाई) = (1,1)। अब मैं इस LAPACK का उपयोग कर हल करने के लिए के रूप में

// LAPACK test code 

#include<iostream> 
#include<vector> 

using namespace std; 
extern "C" void dgetrs(char *TRANS, int *N, int *NRHS, double *A, 
         int *LDA, int *IPIV, double *B, int *LDB, int *INFO); 

int main() 
{ 
    char trans = 'N'; 
    int dim = 2;  
    int nrhs = 1; 
    int LDA = dim; 
    int LDB = dim; 
    int info; 

    vector<double> a, b; 

    a.push_back(1); 
    a.push_back(1); 
    a.push_back(1); 
    a.push_back(-1); 

    b.push_back(2); 
    b.push_back(0); 

    int ipiv[3]; 


    dgetrs(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info); 


    std::cout << "solution is:";  
    std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl; 
    std::cout << "Info = " << info << std::endl; 

    return(0); 
} 

इस प्रकार इस कोड को संकलित किया गया था इस प्रकार की कोशिश की:

g++ -Wall -llapack -lblas lapacktest.cpp

इस चल रहा, हालांकि, मैं के रूप में समाधान प्राप्त (-2,2) जो स्पष्ट रूप से गलत है। मैंने अपने मैट्रिक्स a की पंक्ति/कॉलम पुन: व्यवस्था के सभी संयोजनों का प्रयास किया है। यह भी देखें कि a का मैट्रिक्स प्रतिनिधित्व पंक्ति और कॉलम स्वरूपों में समान होना चाहिए। मुझे लगता है कि काम करने के लिए यह सरल उदाहरण मिलना मुझे लापैक के साथ शुरू कर देगा और किसी भी मदद की सराहना की जाएगी।

+0

क्या LAPACK पुस्तकालय आप उपयोग कर रहे हैं और यह 64 बिट कोड है? – Anycorn

+0

मैं /usr/lib/liblapack.dylib और /usr/lib/libblas.dylib का उपयोग कर रहा हूं जो मैक ओएस-एक्स शेर पर मूल रूप से मौजूद है। मैंने कोई बाहरी लैपैक/बीएलएएस पुस्तकालय स्थापित नहीं किया है। – RDK

+0

उदाहरण में, आप एक सममित मैट्रिक्स को हल कर रहे हैं ताकि आपके पास पंक्ति-प्रमुख या कॉलम-प्रमुख हो, तो आपको कोई अंतर दिखाई नहीं देगा। – SirGuy

उत्तर

21

से पहले आपको dgetrs का उपयोग कर प्रणाली का समाधान कर सकते कारक मैट्रिक्स (dgetrf फोन करके) की जरूरत है। वैकल्पिक रूप से, आप dgesv दिनचर्या का उपयोग कर सकते हैं, जो आपके लिए दोनों कदम करता है।

वैसे, आप अपने आप को इंटरफेस घोषित करने के लिए की जरूरत नहीं है, वे तेजी लाने के शीर्षलेख हैं:

// LAPACK test code 

#include <iostream> 
#include <vector> 
#include <Accelerate/Accelerate.h> 

using namespace std; 

int main() 
{ 
    char trans = 'N'; 
    int dim = 2;  
    int nrhs = 1; 
    int LDA = dim; 
    int LDB = dim; 
    int info; 

    vector<double> a, b; 

    a.push_back(1); 
    a.push_back(1); 
    a.push_back(1); 
    a.push_back(-1); 

    b.push_back(2); 
    b.push_back(0); 

    int ipiv[3]; 

    dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info); 
    dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info); 


    std::cout << "solution is:";  
    std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl; 
    std::cout << "Info = " << info << std::endl; 

    return(0); 
} 
+1

स्टीफन, बहुत बहुत धन्यवाद। यह काम। वैसे, मुझे उम्मीद है कि आप दो अनुवर्ती प्रश्नों का उत्तर देने में मस्तिष्क नहीं करेंगे: (1) मुझे LAPACK का दस्तावेज कहां मिल सकता है जो सभी निर्भरताओं को निर्दिष्ट करता है (जैसे कि डेटर्स से पहले dgetrf का उपयोग करना)। उदाहरण के लिए, मैंने नेटलिब में dgetrs() फ़ंक्शन में जानकारी देखकर अपना मूल प्रोग्राम बनाया। हालांकि, यह नहीं कहा था कि मुझे पहले dgetrf का उपयोग करने के लिए कारक था। (2) मुझे लगता है कि फ्रेमवर्क को तेज करने के लिए, मैं बस -फ्रेमवर्क का उपयोग करके संकलित करता हूं। क्या वो सही है? एक बार फिर से धन्यवाद। – RDK

+1

@ आरडीके: आप या तो फ्रेम-फ्रेम के साथ संकलित कर सकते हैं या आप LAPACK/BLAS के विरुद्ध सीधे लिंक कर सकते हैं जैसा कि आप कर रहे हैं (आप एक ही LAPACK लाइब्रेरी को किसी भी तरह से प्राप्त कर रहे हैं)। नेटलिब पर 'डेटर्स' को देखते हुए वास्तव में * आपको * बताता है कि आपको 'dgetrf'' की आवश्यकता है: "डीजीईटीआरएस डीजीईटीआरएफ द्वारा गणना की गई LU कारक का उपयोग करके सामान्य एन-बाय-एन मैट्रिक्स ए के साथ रैखिक समीकरणों की एक प्रणाली को हल करता है।" हालांकि, एक बेहतर संदर्भ LAPACK उपयोगकर्ता की मार्गदर्शिका होगी, जो नेटलिब पर एचटीएमएल में उपलब्ध है, और एक सस्ते मृत पेड़ के रूप में भी उपलब्ध है। –

+0

आप सही हैं। ऐसा कहता है। बुरी और माफी से। मुझे लगता है मुझे भविष्य में और अधिक ध्यान से पढ़ना है। मैं सस्ते मृत पेड़ के रूप में जा रहा हूं, क्योंकि मेरे सहयोगियों को भी एक संदर्भ में दिलचस्पी होगी। आपके धैर्य और प्रतिक्रियाओं के लिए एक बार फिर धन्यवाद। – RDK

2

आप सी से LAPACK उपयोग करना चाहते हैं ++ आप एक देखो एक FLENS के लिए चाहते हो सकता है । यह कम-और उच्च स्तरीय इंटरफेस को LAPACK में परिभाषित करता है लेकिन कुछ LAPACK फ़ंक्शंस को फिर से लागू करता है।

निम्न-स्तरीय FLENS-LAPACK इंटरफ़ेस के साथ आप अपने मैट्रिक्स/वेक्टर प्रकारों का उपयोग कर सकते हैं (यदि उनके पास LAPACK अनुरूप मेमोरी लेआउट है)। dgetrf का आपका कॉल कि ऐसा दिखाई देगा:

info = lapack::getrf(NoTrans, dim, nrhs, a.begin(), LDA, ipiv); 

और के लिए dgetrs

lapack::getrs(NoTrans, dim, nrhs, a.begin(), LDA, ipiv, b.begin(), LDB); 

तो निम्न स्तर FLENS-LAPACK कार्यों तत्व प्रकार के संबंध में अतिभारित रहे हैं। नतीजतन LAPACK फ़ंक्शन sgetrs, dgetrs, cgetrs, zgetrs FLENS-LAPACK lapack::getrs के निम्न-स्तर इंटरफ़ेस में हैं। आप मूल्य/संदर्भ द्वारा पैरामीटर भी पास करते हैं और पॉइंटर के रूप में नहीं (उदाहरण के लिए LDA&LDA के बजाय)।

यदि आप FLENS मैट्रिक्स प्रकार का उपयोग आप इसे के रूप में

info = lapack::trf(NoTrans, A, ipiv); 
if (info==0) { 
    lapack::trs(NoTrans, A, ipiv, b); 
} 

कोड कर सकते हैं या फिर आप LAPACK ड्राइवर समारोह dgesv

lapack::sv(NoTrans, A, ipiv, b); 

यहाँ एक list of FLENS-LAPACK ड्राइवर कार्यों का उपयोग।

अस्वीकरण: हाँ, FLENS मेरा बच्चा है! इसका मतलब है कि मैंने इसमें से 9 5% कोड किया था और कोड की हर पंक्ति इसके लायक थी।

+0

FLENS LAPACK/C++ को इंटरफ़ेस करने का एक शानदार तरीका दिखता है। मैं इसे जांचना सुनिश्चित करूँगा। – RDK

5

जो लोग तेजी लाने की रूपरेखा से परेशान नहीं करना चाहते हैं के लिए, मैं (उसे करने के लिए धन्यवाद ज़ाहिर है,) कुछ नहीं बल्कि शुद्ध पुस्तकालय

// LAPACK test code 
//compile with: g++ main.cpp -llapack -lblas -o testprog 

#include <iostream> 
#include <vector> 

using namespace std; 

extern "C" void dgetrf_(int* dim1, int* dim2, double* a, int* lda, int* ipiv, int* info); 
extern "C" void dgetrs_(char *TRANS, int *N, int *NRHS, double *A, int *LDA, int *IPIV, double *B, int *LDB, int *INFO); 

int main() 
{ 
    char trans = 'N'; 
    int dim = 2; 
    int nrhs = 1; 
    int LDA = dim; 
    int LDB = dim; 
    int info; 

    vector<double> a, b; 

    a.push_back(1); 
    a.push_back(1); 
    a.push_back(1); 
    a.push_back(-1); 

    b.push_back(2); 
    b.push_back(0); 

    int ipiv[3]; 

    dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info); 
    dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info); 


    std::cout << "solution is:"; 
    std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl; 
    std::cout << "Info = " << info << std::endl; 

    return(0); 
} 

जोड़ने के साथ और मार्गदर्शन के बारे में स्टीफन कैनन का कोड प्रदान करते हैं इंटेल की वेबसाइट पर एक पूर्ण पीडीएफ संस्करण उपलब्ध है। यहां उनके HTML दस्तावेज़ का नमूना है।

http://software.intel.com/sites/products/documentation/hpc/mkl/mklman/GUID-A02DB70F-9704-42A4-9071-D409D783D911.htm

+1

यह कोड उदाहरण बहुत उपयोगी था। मुझे यह पहचानने में मदद मिली कि LAPACK पुस्तकालयों की मेरी प्रति मेरे प्रोजेक्ट से सही ढंग से जुड़ी नहीं थी। – NoseKnowsAll

संबंधित मुद्दे