NumPy benzeri dizilere sahip C ++ (veya C) kitaplıkları, dilimleme, vektörleştirilmiş işlemler, öğe öğe ekleme ve çıkarma vb. Desteği olan var mı?
NumPy benzeri dizilere sahip C ++ (veya C) kitaplıkları, dilimleme, vektörleştirilmiş işlemler, öğe öğe ekleme ve çıkarma vb. Desteği olan var mı?
Yanıtlar:
İşte ihtiyaçlarınızı karşılayabilecek birkaç özgür yazılım.
GNU Bilimsel Kütüphanesi Böylece C ile yazılmış bir GPL yazılımı, bir C-benzeri programlama (işaretçiler, vb) tahsisi ve yol vardır. İle GSLwrap hala GSL kullanırken, sen programlama C ++ yol olabilir. GSL'nin bir BLAS uygulaması vardır, ancak daha fazla performans istiyorsanız, varsayılan CBLAS yerine ATLAS kullanabilirsiniz .
Boost / uBLAS kütüphanesi BSL kütüphanesi, C ++ yazılmış ve bir destek paket olarak dağıtılır. BLAS standardını uygulamanın bir C ++ yoludur. uBLAS, birkaç doğrusal cebir fonksiyonuyla birlikte gelir ve ATLAS'a deneysel bir bağlanma vardır .
eigen , MPL2 lisansı (3.1.1 sürümünden başlayarak) veya LGPL3 / GPL2 (eski sürümler) altında dağıtılan, C ++ ile yazılmış doğrusal bir cebir kitaplığıdır. Bu bir C ++ programlama şeklidir, ancak diğer ikisinden daha entegre (daha fazla algoritma ve veri yapısı mevcuttur). Eigen , fiili standart BLAS API'yi takip etmemekle birlikte yukarıdaki BLAS uygulamalarından daha hızlı olduğunu iddia ediyor . Eigen, paralel uygulama için fazla çaba sarf etmiyor gibi görünüyor.
Armadillo , C ++ için LGPL3 kitaplığıdır. LAPACK (numpy tarafından kullanılan kütüphane) için bağlayıcılığı vardır . Özyinelemeli şablonlar ve şablon meta programlama kullanır, bu iyi bir noktadır (diğer kütüphanelerin de bunu yapıp yapmadığını bilmiyorum?).
xtensor , BSD lisanslı bir C ++ kitaplığıdır. NumPy'ye çok benzer bir C ++ API sunar. Hile sayfası için https://xtensor.readthedocs.io/en/latest/numpy.html adresine bakın .
Yalnızca veri yapılarını ve temel doğrusal cebiri elde etmek istiyorsanız, bu alternatifler gerçekten iyidir. Stil, lisans veya sysadmin zorlukları hakkındaki zevkinize bağlı olarak (LAPACK gibi büyük kitaplıklar kurmak zor olabilir), ihtiyaçlarınıza en uygun olanı seçebilirsiniz.
a[:4,::-1,:,19] = b[None,-5:,None]
veya a[a>5]=0
benzeri şeyleri destekler , ayrıca çok sayıda dizi ve dizin işleme işlevine sahiptir. Umarım bir gün birileri C ++ için böyle bir şey yapar.
a.colRange(4,7).rowRange(4,8)
için a[4:7,4,8]
) ve koşul maskesi ( a.setTo(cv::Scalar(0), a>5)
için a[a>5]=0
)
Xtensor'u deneyin . ( NumPy'den Xtensor'a Hile Sayfasına bakın ).
xtensor, çok boyutlu dizi ifadeleri ile sayısal analiz için tasarlanmış bir C ++ kitaplığıdır.
xtensor sağlar
Misal
2 boyutlu bir diziyi başlatın ve satırlarından birinin ve 1 boyutlu dizinin toplamını hesaplayın.
#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
xt::xarray<double> arr1
{{1.0, 2.0, 3.0},
{2.0, 5.0, 7.0},
{2.0, 5.0, 7.0}};
xt::xarray<double> arr2
{5.0, 6.0, 7.0};
xt::xarray<double> res = xt::view(arr1, 1) + arr2;
std::cout << res;
çıktılar
{7, 11, 14}
Bir 1-D dizisini başlatın ve yerinde yeniden şekillendirin.
#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
xt::xarray<int> arr
{1, 2, 3, 4, 5, 6, 7, 8, 9};
arr.reshape({3, 3});
std::cout << arr;
çıktılar
{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}
DyND , diğer şeylerin yanı sıra C ++ için NumPy benzeri bir kitaplık olacak şekilde tasarlanmıştır. Yayın, aritmetik operatörler ve dilimleme gibi şeyler iyi çalışıyor. Öte yandan, hala çok deneysel ve birçok özellik henüz uygulanmadı.
DyND dizilerini kullanarak C ++ 'da de Casteljau algoritmasının basit bir uygulaması:
#include <iostream>
#include <dynd/array.hpp>
using namespace dynd;
nd::array decasteljau(nd::array a, double t){
size_t e = a.get_dim_size();
for(size_t i=0; i < e-1; i++){
a = (1.-t) * a(irange()<(e-i-1)) + t * a(0<irange());
}
return a;
}
int main(){
nd::array a = {1., 2., 2., -1.};
std::cout << decasteljau(a, .25) << std::endl;
}
Kısa bir süre önce Fortran 90, C ++ 'da DyND ve Python'da NumPy için sözdiziminin daha fazla örneği ve yan yana karşılaştırmalarını içeren bir blog yazısı yazdım .
Sorumluluk reddi: Ben mevcut DyND geliştiricilerinden biriyim.
Eigen, iyi bir doğrusal cebir kütüphanesidir.
http://eigen.tuxfamily.org/index.php?title=Main_Page
Yalnızca başlık içeren bir kitaplık olduğu için kurulumu oldukça kolaydır. İyi optimize edilmiş kod oluşturmak için şablona dayanır. Matris işlemlerini otomatik olarak vektörleştirir.
Aynı zamanda, örneğin iki matris arasındaki "eleman başına çarpma" gibi katsayı bilge işlemleri tam olarak destekler. İhtiyacın olan bu mu?
Blitz ++ , keyfi sayıda eksen içeren dizileri desteklerken, Armadillo yalnızca üç adede kadar (vektörler, matrisler ve küpler) destekler. Eigen yalnızca vektörleri ve matrisleri destekler (küpleri değil). Dezavantajı, Blitz ++ 'nın temel girişsel işlemlerin ve tensör kasılmalarının ötesinde doğrusal cebir işlevlerine sahip olmamasıdır. Geliştirme epey bir zaman önce yavaşlamış gibi görünüyor, ama belki de bunun nedeni kütüphanenin yaptığını yapması ve çok fazla değişikliğin yapılmasına gerek olmamasıdır.
xtensor iyidir, ancak arayüzü olabildiğince basit tutmaya çalışırken c ++ 20 ile bir oyuncak projesi olarak kendime bir mini kitaplık yazdım. İşte burada: https://github.com/gbalduzz/NDArray
Örnek kod:
using namespace nd;
NDArray<int, 2> m(3, 3); // 3x3 matrix
m = 2; // assign 2 to all
m(-1, all) = 1; // assign 1 to the last row.
auto tile = m(range{1, end}, range{1, end}); // 2x2 tile
std::sort(tile.begin(), tile.end());
std::cout << m; // prints [[2, 2, 2], [2, 1, 1], [1, 2, 2]]
Birden çok işlemi birlikte daraltan fantezi aritmetik operatörler sağlamaz, ancak aynı şekle sahip bir tensöre rastgele lambdalar yayınlayabilir veya tembel olarak değerlendirilmiş aritmetik operatörleri kullanabilirsiniz.
Arayüz hakkında ne düşündüğünüzü ve diğer seçeneklerle nasıl karşılaştırıldığını ve bunun herhangi bir umudu varsa, ne tür operasyonların uygulanmasını istediğinizi bana bildirin.
Ücretsiz lisans ve bağımlılık yok!
Ek: xtensor'u düzgün bir şekilde derlemeyi ve çalıştırmayı başardım ve sonuç olarak, görünümler üzerinde yinelendiğinde kütüphanem önemli ölçüde daha hızlıdır (2 ila 3X)
VIGRA iyi bir N boyutlu dizi uygulaması içerir:
http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html
Yaygın olarak kullanıyorum ve çok basit ve etkili buluyorum. Ayrıca yalnızca başlıktır, geliştirme ortamınıza entegre etmek çok kolaydır. NumPy'yi API açısından kullandığım en yakın şey bu.
Başlıca dezavantajı, diğerleri kadar yaygın olarak kullanılmamasıdır, bu nedenle çevrimiçi olarak fazla yardım bulamazsınız. Bu ve garip bir şekilde adlandırıldı (aramayı deneyin!)
LibTorch (C ++ için PyTorch ön ucu) kullanın ve mutlu olun.
Bu eski bir sorudur. Hâlâ cevap veriyor gibiydi. Pek çok kişiye yardımcı olabileceğini düşündüm, özellikle de C ++ ile kodlayan pydevs.
Python numpy ile zaten çalıştıysanız, NumCpp harika bir seçimdir. Sözdiziminde minimalisttir ve py numpy ile benzer işlevlere veya yöntemlere sahiptir.
Karşılaştırma benioku doc part çok çok serin aynı zamanda.
NumCpp
nc::NdArray<int> arr = {{4, 2}, {9, 4}, {5, 6}};
arr.reshape(5, 3);
arr.astype<double>();
Görüntü işleme veya sinir ağı için çok boyutlu dizi (numpy gibi) kullanmak istiyorsanız, OpenCV
cv::Mat
tonlarca görüntü işleme algoritmasıyla birlikte kullanabilirsiniz . YALNIZCA matris işlemleri için kullanmak istemeniz durumunda, boyutu küçültmek ve küçük OpenCV kitaplığına sahip olmak için ilgili açıklık modüllerini derlemeniz yeterlidir.
cv::Mat
(Matris), RGB, HSV veya gri tonlamalı görüntüler, gerçek veya karmaşık değerli vektörler, diğer matrisler vb. Gibi çeşitli veri türlerini depolamak için kullanılabilen n boyutlu bir dizidir.
Bir Paspas aşağıdaki bilgileri içerir: width, height, type, channels, data, flags, datastart, dataend
vb.
Matris manipülasyonu için birkaç yöntemi vardır. Bonus daha sonra CUDA çekirdeklerinde de oluşturabilirsiniz cv::cuda::GpuMat
.
10 satır, 20 sütunlu bir matris oluşturmak istediğimi düşünün, CV_32FC3 yazın:
int R = 10, C = 20;
Mat m1;
m1.create(R, C, CV_32FC3); //creates empty matrix
Mat m2(cv::Size(R, C), CV_32FC3); // creates a matrix with R rows, C columns with data type T where R and C are integers,
Mat m3(R, C, CV_32FC3); // same as m2
BONUS:
Yalnızca matris işlemleri için küçük ve kompakt açıklıklı kitaplık derleyin. Yollardan biri bu makalede belirtildiği gibidir.
VEYA
aşağıdaki cmake komutunu kullanarak opencv kaynak kodunu derleyin:
$ git clone https://github.com/opencv/opencv.git
$ cd opencv
$ git checkout <version you want to checkout>
$ mkdir build
$ cd build
$ cmake -D WITH_CUDA=OFF -D WITH_MATLAB=OFF -D BUILD_ANDROID_EXAMPLES=OFF -D BUILD_DOCS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -DANDROID_STL=c++_shared -DBUILD_SHARED_LIBS=ON -D BUILD_opencv_objdetect=OFF -D BUILD_opencv_video=OFF -D BUILD_opencv_videoio=OFF -D BUILD_opencv_features2d=OFF -D BUILD_opencv_flann=OFF -D BUILD_opencv_highgui=OFF -D BUILD_opencv_ml=OFF -D BUILD_opencv_photo=OFF -D BUILD_opencv_python=OFF -D BUILD_opencv_shape=OFF -D BUILD_opencv_stitching=OFF -D BUILD_opencv_superres=OFF -D BUILD_opencv_ts=OFF -D BUILD_opencv_videostab=OFF -D BUILD_opencv_dnn=OFF -D BUILD_opencv_imgproc=OFF ..
$ make -j $nproc
$ sudo make install
Bu örneği deneyin:
#include "opencv2/core.hpp"
#include<iostream>
int main()
{
std::cout << "OpenCV Version " << CV_VERSION << std::endl;
int R = 2, C = 4;
cv::Mat m1;
m1.create(R, C, CV_32FC1); //creates empty matrix
std::cout << "My Mat : \n" << m1 << std::endl;
}
Kodu aşağıdaki komutla derleyin:
$ g++ -std=c++11 opencv_mat.cc -o opencv_mat `pkg-config --libs opencv` `pkg-config --cflags opencv`
Yürütülebilir dosyayı çalıştırın:
$ ./opencv_mat
OpenCV Version 3.4.2
My Mat :
[0, 0, 0, 0;
0, 0, 0, 0]
GSL size soran ve çok daha fazlası şeyin hepsini yapıyor, harika. Yine de GPL altında lisanslanmıştır.
İken GLM OpenGL ve GLSL ile kolayca örgü için tasarlanmıştır, bu arayüzler çok sezgisel bir set ile C için tamamen işlevsel başlık sadece matematik kütüphanesi ++ olduğunu.
Vektör ve matris türlerini ve bunlarla ilgili çeşitli işlemleri bildirir.
İki matrisi çarpmak (M1 * M2) kadar basittir. İki vektörün çıkarılması (V1-V2).
Vektörlerde veya matrislerde bulunan değerlere erişmek de aynı derecede basittir. Örneğin bir vec3 vektörü bildirdikten sonra, ilk elemanına vector.x ile erişilebilir. Bunu kontrol et.