সি ++ এ কীভাবে ল্যাপ্যাক ব্যবহার শুরু করবেন?


10

আমি কম্পিউটেশনাল সায়েন্সে নতুন এবং আমি ইতোমধ্যে সি ++ তে ইন্টিগ্রেশন, ইন্টারপোলেশন, আরকে 4, নুমেরভ ইত্যাদির জন্য প্রাথমিক পদ্ধতিগুলি শিখেছি তবে সম্প্রতি আমার প্রফেসর আমাকে ম্যাট্রিক সম্পর্কিত সমস্যা সমাধানের জন্য কীভাবে ল্যাপ্যাক ব্যবহার করবেন তা শিখতে বলেছিলেন। উদাহরণস্বরূপ একটি জটিল ম্যাট্রিক্সের ইগেনভ্যালুগুলি সন্ধান করুন। আমি কখনও তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করি নি এবং আমি প্রায় সবসময় নিজের ফাংশনগুলি লিখি। আমি বেশ কয়েক দিন ধরে ঘুরে দেখছিলাম তবে কোথাও কোনও অপেশাদার-বান্ধব গাইড খুঁজে পাচ্ছি না। এগুলির সবগুলি এমন কথায় লেখা যা আমি বুঝতে পারি না এবং আমি জানি না কেন ইতিমধ্যে লিখিত ফাংশনগুলি ব্যবহার করা এই জটিল হওয়া উচিত। এগুলি জিগিয়েভ, ডিটিআরএসভি ইত্যাদির মতো শব্দে পূর্ণ এবং আমি হতাশ। আমি কেবল এই সিডো-কোডের মতো কিছু কোড করতে চাই:

#include <lapack:matrix>
int main(){
  LapackComplexMatrix A(n,n);
  for...
   for...
    cin>>A(i,j);
  cout<<LapackEigenValues(A);
  return 0;
}

আমি বোকা বা অপেশাদার হয়েছি কিনা জানি না। কিন্তু আবার, এটি কি এমন হওয়া উচিত নয়? এমনকি আমি জানি না যে আমার ল্যাপাক বা ল্যাপ্যাক ++ ব্যবহার করা উচিত। (আমি কোডগুলি সি ++ তে লিখি এবং পাইথন বা ফরটারনের কোনও জ্ঞান নেই) এবং সেগুলি কীভাবে ইনস্টল করব।


সম্ভবত এই উদাহরণটি কার্যকর হবে: matrixprogramming.com/files/code/LAPACK
nukeguy

আপনি যদি এখনই শুরু করে থাকেন তবে অ্যারেফায়ার github.com/arrayfire/arrayfire এর মত সহজ লাইব্রেরি ব্যবহার করা আরও সহজ হবে । আপনি এটি সরাসরি সি ++ থেকে কল করতে পারেন এবং এপিআই এর সহজতর এবং আমি মনে করি এটি ল্যাপাকের মতো সমস্ত অপারেশন করতে পারে।
বিক্রম

এই অন্যান্য পোস্টে একজন ব্যবহারকারী তার নিজের র‍্যাপার FLENS এর প্রস্তাব দেয়, যার একটি খুব সুন্দর বাক্য গঠন রয়েছে যা ল্যাপকের সাথে আপনার পরিচয় সহজ করতে পারে।
জাইথোস

LAPACK ফাংশনগুলিকে সরাসরি কল করা খুব ক্লান্তিকর এবং ত্রুটিযুক্ত প্রবণ। বিভিন্ন ব্যবহারকারী বান্ধব সি ++ যেমন LAPACK জন্য চাদরে যা অনেক সহজ ব্যবহার প্রদান হয় আরমাডিলো । জটিল ইয়েজেন পচনের নির্দিষ্ট ব্যবহারের ক্ষেত্রে, ব্যবহারকারী-বান্ধব eig_gen () ফাংশনটি দেখুন যা এই ল্যাপ্যাক মনস্ট্রোসিটির নীচে জেপ করে (জোবজেড, ইউপিএলও, এন, এ, এলডিএ, ডাব্লু, ওয়ার্ক, লবর্ক, রোবর্ক, ইনফো), এবং প্রাপ্ত ইগেনভ্যালু এবং ইগেনভেেক্টরগুলিকে স্ট্যান্ডার্ড উপস্থাপনায় রূপান্তর করে।
hbrrkere

উত্তর:


18

আমি অন্য কয়েকটি উত্তরগুলির সাথে একমত নই এবং বলব যে আমি বিশ্বাস করি যে বৈজ্ঞানিক কম্পিউটিংয়ের ক্ষেত্রে কীভাবে ল্যাপ্যাক ব্যবহার করবেন তা নির্ধারণ করা গুরুত্বপূর্ণ।

তবে ল্যাপাক ব্যবহারের জন্য একটি বৃহত শিক্ষার বক্ররেখা রয়েছে। এটি খুব নিম্ন স্তরে লেখা হয়েছে কারণ এটি। এর অসুবিধাটি হ'ল এটি অত্যন্ত গুপ্ত এবং ইন্দ্রিয়গুলির কাছে সুখকর নয়। এর সুবিধাটি হ'ল ইন্টারফেসটি দ্ব্যর্থহীন এবং মূলত কখনই পরিবর্তন হয় না। অতিরিক্তভাবে, ল্যাপাকের বাস্তবায়ন যেমন ইন্টেল ম্যাথ কার্নেল লাইব্রেরিটি সত্যিই দ্রুত।

আমার নিজের উদ্দেশ্যে, আমার নিজস্ব উচ্চ স্তরের সি ++ ক্লাস রয়েছে যা ল্যাপাক সাবউরাইনগুলিকে প্রায় আবৃত করে। অনেকগুলি বৈজ্ঞানিক গ্রন্থাগার নীচে ল্যাপাক ব্যবহার করে। কখনও কখনও কেবল সেগুলি ব্যবহার করা সহজ তবে আমার মতে নীচের সরঞ্জামটি বোঝার অনেক মূল্য আছে। সে লক্ষ্যে, আমি আপনাকে শুরু করতে ল্যাপাক ব্যবহার করে সি ++ তে লিখিত একটি ছোট্ট কাজের উদাহরণ সরবরাহ করেছি। এটি উবুন্টুতে liblapack3প্যাকেজ ইনস্টলড এবং বিল্ডিংয়ের জন্য অন্যান্য প্রয়োজনীয় প্যাকেজ সহ কাজ করে। এটি সম্ভবত বেশিরভাগ লিনাক্স বিতরণে ব্যবহার করা যেতে পারে, তবে ল্যাপাক ইনস্টল করা এবং এর বিপরীতে লিঙ্ক করা ভিন্ন হতে পারে।

ফাইলটি এখানে test_lapack.cpp

#include <iostream>
#include <fstream>


using namespace std;

// dgeev_ is a symbol in the LAPACK library files
extern "C" {
extern int dgeev_(char*,char*,int*,double*,int*,double*, double*, double*, int*, double*, int*, double*, int*, int*);
}

int main(int argc, char** argv){

  // check for an argument
  if (argc<2){
    cout << "Usage: " << argv[0] << " " << " filename" << endl;
    return -1;
  }

  int n,m;
  double *data;

  // read in a text file that contains a real matrix stored in column major format
  // but read it into row major format
  ifstream fin(argv[1]);
  if (!fin.is_open()){
    cout << "Failed to open " << argv[1] << endl;
    return -1;
  }
  fin >> n >> m;  // n is the number of rows, m the number of columns
  data = new double[n*m];
  for (int i=0;i<n;i++){
    for (int j=0;j<m;j++){
      fin >> data[j*n+i];
    }
  }
  if (fin.fail() || fin.eof()){
    cout << "Error while reading " << argv[1] << endl;
    return -1;
  }
  fin.close();

  // check that matrix is square
  if (n != m){
    cout << "Matrix is not square" <<endl;
    return -1;
  }

  // allocate data
  char Nchar='N';
  double *eigReal=new double[n];
  double *eigImag=new double[n];
  double *vl,*vr;
  int one=1;
  int lwork=6*n;
  double *work=new double[lwork];
  int info;

  // calculate eigenvalues using the DGEEV subroutine
  dgeev_(&Nchar,&Nchar,&n,data,&n,eigReal,eigImag,
        vl,&one,vr,&one,
        work,&lwork,&info);


  // check for errors
  if (info!=0){
    cout << "Error: dgeev returned error code " << info << endl;
    return -1;
  }

  // output eigenvalues to stdout
  cout << "--- Eigenvalues ---" << endl;
  for (int i=0;i<n;i++){
    cout << "( " << eigReal[i] << " , " << eigImag[i] << " )\n";
  }
  cout << endl;

  // deallocate
  delete [] data;
  delete [] eigReal;
  delete [] eigImag;
  delete [] work;


  return 0;
}

এটি কমান্ড লাইন ব্যবহার করে নির্মিত যেতে পারে

g++ -o test_lapack test_lapack.cpp -llapack

এটি একটি এক্সিকিউটেবল নামের উত্পাদন করবে test_lapack। আমি এটি একটি পাঠ্য ইনপুট ফাইলে পড়তে সেট আপ করেছি। এখানে matrix.txt3x3 ম্যাট্রিক্সযুক্ত একটি ফাইল রয়েছে ।

3 3
-1.0 -8.0  0.0
-1.0  1.0 -5.0
 3.0  0.0  2.0

প্রোগ্রামটি চালাতে সহজভাবে টাইপ করুন

./test_lapack matrix.txt

কমান্ড লাইনে এবং আউটপুট হওয়া উচিত

--- Eigenvalues ---
( 6.15484 , 0 )
( -2.07742 , 3.50095 )
( -2.07742 , -3.50095 )

মন্তব্যসমূহ:

  • আপনি ল্যাপাকের নামকরণের স্কিমটি ফেলে দিয়েছেন বলে মনে হচ্ছে। একটি সংক্ষিপ্ত বিবরণ এখানে
  • ডিজিইভি সাবউরোটিনের ইন্টারফেসটি এখানে । আপনার এখানে যুক্তিগুলির বিবরণটি তুলনা করতে সক্ষম হওয়া উচিত।
  • extern "C"উপরের অংশটি নোট করুন এবং আমি এতে একটি আন্ডারস্কোর যুক্ত করেছি dgeev_। কারণ লাইব্রেরিটি ফোর্টরানে রচিত এবং নির্মিত হয়েছিল, সুতরাং সংযোগের সময় প্রতীকগুলি মেলাতে এটি প্রয়োজনীয়। এটি সংকলক এবং সিস্টেম নির্ভর, সুতরাং আপনি যদি এটি উইন্ডোতে ব্যবহার করেন তবে এটি সমস্ত পরিবর্তন করতে হবে।
  • কিছু লোক LAPACKসি ইন্টারফেস ব্যবহার করার পরামর্শ দিতে পারে । এগুলি সঠিক হতে পারে তবে আমি সর্বদা এটি এইভাবে করেছি।

3
আপনি যা সন্ধান করছেন তার অনেকগুলি দ্রুত গুগলেজের সাথে পাওয়া যায়। সম্ভবত আপনি কী অনুসন্ধান করবেন তা নিশ্চিত নন। নেটলিব ল্যাপাকের রক্ষক। ডকুমেন্টেশন এখানে পাওয়া যাবেএই পৃষ্ঠায় ল্যাপাকের মূল কার্যকারিতাটির একটি সহজ টেবিল রয়েছে। কয়েকটি গুরুত্বপূর্ণ বিষয় হ'ল (১) সমীকরণের সিস্টেমগুলি সমাধান করা, (২) ইগেনুয়ালুয় সমস্যা, (৩) একক মানের মূল্য পচন এবং (৪) কিউআর ফ্যাক্টরীকরণ। আপনি ডিজিইইভিটির জন্য ম্যানুয়ালটি বুঝতে পেরেছিলেন?
নেতৃত্বাধীন

1
তারা সমস্ত একই জিনিস একই জন্য বিভিন্ন ইন্টারফেস। ল্যাপাক আসল। এটি ফোর্টরানে লেখা আছে, সুতরাং এটি ব্যবহার করতে আপনাকে সি / সি ++ কাজ থেকে ক্রস-সংকলন করতে কিছু গেম খেলতে হবে, যেমন আমি দেখিয়েছি। আমি কখনও ল্যাপাক ব্যবহার করি নি, তবে দেখে মনে হচ্ছে এটি ল্যাপাকের চেয়ে বেশ পাতলা সি র‍্যাপার যা এই ক্রস সংকলন ব্যবসা এড়িয়ে চলে, তবে এটি এখনও বেশ নিম্ন স্তরের। ল্যাপাক ++ এটি এমনকি উচ্চতর স্তরের সি ++ র‌্যাপার হিসাবে উপস্থিত বলে মনে হয়, তবে আমি মনে করি না এটি আরও সমর্থিত (কেউ যদি আমার ভুল হয় তবে আমাকে সংশোধন করে)।
নেতৃত্বাধীন

1
আমি কোনও নির্দিষ্ট কোড সংগ্রহ জানি না। তবে আপনি যদি কোনও ল্যাপাক সাববুটিন নাম গুগল করেন তবে আপনি স্ট্যাক এক্সচেঞ্জ সাইটের কোনওটিতে অবিচ্ছিন্নভাবে একটি পুরানো প্রশ্ন খুঁজে পাবেন।
নেতৃত্বাধীন

1
@ আলিরেজা হাশেমি যাইহোক, আপনাকে ওয়ার্ক অ্যারে সরবরাহ করার কারণ হ'ল নিয়ম হিসাবে ল্যাপাক তার সাব্রোটিনগুলির ভিতরে কোনও স্মৃতি বরাদ্দ করে না। যদি আমরা ল্যাপাক ব্যবহার করি তবে আমরা সম্ভবত মেমরির গাবগুলি ব্যবহার করছি, এবং মেমরি বরাদ্দ করা ব্যয়বহুল, সুতরাং কলিং রুটিনগুলিকে মেমরি বরাদ্দের দায়িত্বে রাখা উচিত তা বোঝা যায়। যেহেতু ডিজিইভিভের অন্তর্বর্তী পরিমাণ সংরক্ষণের জন্য মেমরির প্রয়োজন হয়, তাই আমাদের এটির কার্যক্ষম স্থান সরবরাহ করতে হবে।
লেডহিড

1
বুঝেছি. এবং আমি জেজিভ ব্যবহার করে একটি জটিল ম্যাট্রিক্সের ইগেনভ্যালু গণনা করার জন্য আমার প্রথম কোডটি সফলভাবে লিখেছি। এবং ইতিমধ্যে আরও করছেন! ধন্যবাদ!
আলিরিজা

7

আমি সাধারণত লোকদের তাদের প্রশ্নের জবাব দেওয়ার চেয়ে তাদের কী করা উচিত বলে আমি বলার বিরোধিতা করি তবে এই ক্ষেত্রে আমি একটি ব্যতিক্রম করতে যাচ্ছি।

ল্যাপাক ফরটারনে লেখা আছে এবং এপিআই খুব ফোরট্রান-মতো। ল্যাপকে সি সি এপিআই রয়েছে যা ইন্টারফেসটি কিছুটা কম বেদনাদায়ক করে তোলে তবে সি ++ থেকে ল্যাপ্যাকটি ব্যবহার করা কখনই একটি সুখকর অভিজ্ঞতা হবে না।

অন্যথা, সেখানে একটি সি ++ ম্যাট্রিক্স বর্গ গ্রন্থাগার বলা হয় Eigen Lapack ক্ষমতার অনেক আছে, গণনীয় কর্মক্ষমতা ভাল Lapack বাস্তবায়নের সঙ্গে তুলনীয় প্রদান করে, এবং খুব সি ++ থেকে ব্যবহার করতে সুবিধাজনক। বিশেষত, আইগেন ব্যবহার করে আপনার উদাহরণ কোডটি কীভাবে রচিত হতে পারে তা এখানে

#include <iostream>
using std::cout;
using std::endl;

#include <Eigen/Eigenvalues>

int main()
{
  const int n = 4;
  Eigen::MatrixXd a(n, n);
  a <<
    0.35, 0.45, -0.14, -0.17,
    0.09, 0.07, -0.54, 0.35,
    -0.44, -0.33, -0.03, 0.17,
    0.25, -0.32, -0.13, 0.11;
  Eigen::EigenSolver<Eigen::MatrixXd> es;
  es.compute(a);
  Eigen::VectorXcd ev = es.eigenvalues();
  cout << ev << endl;
}

এই উদাহরণটি ইগেনুয়ালু সমস্যা ল্যাপ ফাংশনের জন্য একটি পরীক্ষার কেস dgeev। আপনি এই সমস্যাটির উদাহরণস্বরূপ ফরটার কোড এবং ফলাফল দেখতে পারেন এবং নিজের তুলনা তৈরি করতে পারেন।


আপনার উত্তর এবং ব্যাখ্যা জন্য আপনাকে ধন্যবাদ! আমি এই লাইব্রেরিটি ব্যবহার করে চেষ্টা করব এবং আমার প্রয়োজন অনুসারে সবচেয়ে উপযুক্ত একটি বেছে নেব।
আলিরিজা

ওহ, ওভারলোড operator,! প্রকৃত অনুশীলনে এটি কখনও কখনও দেখা যায়নি :-)
ওল্ফগ্যাং ব্যাঙ্গার্থ

1
আসলে, operator,ওভারলোডটি এটির আগে প্রদর্শিত হওয়ার চেয়ে আরও আকর্ষণীয় / ভাল। এটি ম্যাট্রিকেস শুরু করার জন্য ব্যবহৃত হয়। ম্যাট্রিক্স সূচনা করে এমন এন্ট্রিগুলি স্কেলার ধ্রুবক হতে পারে তবে এটি পূর্ব নির্ধারিত ম্যাট্রিক বা সাব-ম্যাট্রিক্সও হতে পারে। খুব ম্যাটল্যাবের মতো। আমার সি ++ প্রোগ্রামিংয়ের দক্ষতা এমন কিছু বাস্তবায়নের জন্য যথেষ্ট যথেষ্ট ছিল যা নিজেকে পরিশীলিত করে ;-)
বিল গ্রিন

7

উপরের মত একই শিরাতে এখানে আরও একটি উত্তর দেওয়া আছে।

আপনার আর্মাদিলো সি ++ লিনিয়ার বীজগণিত গ্রন্থাগারটি সন্ধান করা উচিত ।

পেশাদাররা:

  1. ফাংশন সিনট্যাক্সটি উচ্চ-স্তরের (ম্যাটল্যাবের মতো)। সুতরাং কোনও DGESVমাম্বো-জাম্বো নেই, কেবল X = solve( A, B )(যদিও এই অদ্ভুতভাবে দেখা ল্যাপাক ফাংশন নামগুলির পিছনে কোনও কারণ রয়েছে ...)।
  2. বিভিন্ন ম্যাট্রিক্স পচানোর (এলইউ, কিউআর, ইগেনভ্যালু, এসভিডি, কোলেস্কি ইত্যাদি) কার্যকর করে
  3. সঠিকভাবে ব্যবহার করার সময় এটি দ্রুত হয়।
  4. এটি ভাল নথিভুক্ত করা হয়
  5. স্পার্স ম্যাট্রিক্সের জন্য সমর্থন রয়েছে (আপনি পরে এগুলি দেখতে চাইবেন)।
  6. অনুকূল পারফরম্যান্সের জন্য আপনি এটি আপনার অতি-অনুকূলিত BLAS / ল্যাপাক লাইব্রেরির বিপরীতে লিঙ্ক করতে পারেন।

আর্মাদিলোর সাথে @ বিলগ্রিনের কোডটি কেমন দেখাচ্ছে তা এখানে:

#include <iostream>
#include <armadillo>

using namespace std;
using namespace arma;

int main()
{
   const int k = 4;
   mat A = zeros<mat>(k,k) // mat == Mat<double>

   // with the << operator...
   A <<
    0.35 << 0.45 << -0.14 << -0.17 << endr
    0.09 << 0.07 << -0.54 << 0.35  << endr
    -0.44 << -0.33 << -0.03 << 0.17 << endr
    0.25 << -0.32 << -0.13 << 0.11 << endr;

   // but using an initializer list is faster
   A = { {0.35, 0.45, -0.14, -0.17}, 
         {0.09, 0.07, -0.54, 0.35}, 
         {-0.44, -0.33, -0.03, 0.17}, 
         {0.25, -0.32, -0.13, 0.11} };

   cx_vec eigval; // eigenvalues may well be complex
   cx_mat eigvec;

   // eigenvalue decomposition for general dense matrices
   eig_gen(eigval, eigvec, A);

   std::cout << eigval << std::endl;

   return 0;
}

আপনার উত্তর এবং ব্যাখ্যা জন্য আপনাকে ধন্যবাদ! আমি এই লাইব্রেরিটি ব্যবহার করে চেষ্টা করব এবং আমার প্রয়োজন অনুসারে সবচেয়ে উপযুক্ত একটি বেছে নেব।
আলিরিজা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.