Существуют ли какие-либо библиотеки C ++ (или C) с массивами, подобными NumPy, с поддержкой нарезки, векторизованных операций, добавления и вычитания содержимого по элементам и т. Д.?
c++
arrays
dynamic-arrays
Ламагедон
источник
источник
Ответы:
Вот несколько бесплатных программ, которые могут удовлетворить ваши потребности.
GNU Scientific Library является GPL программное обеспечение , написанное на языке C. Таким образом, он имеет С-подобного распределения и способ программирования (указатели и т.д.). С GSLwrap вы можете программировать на C ++, продолжая использовать GSL. GSL имеет реализацию BLAS , но вы можете использовать ATLAS вместо CBLAS по умолчанию, если хотите еще больше производительности.
Библиотека boost / uBLAS - это библиотека BSL, написанная на C ++ и распространяемая как пакет boost. Это C ++ - способ реализации стандарта BLAS. uBLAS поставляется с несколькими функциями линейной алгебры, и есть экспериментальная привязка к ATLAS .
eigen - это библиотека линейной алгебры, написанная на C ++, распространяется по лицензии MPL2 (начиная с версии 3.1.1) или LGPL3 / GPL2 (более старые версии). Это способ программирования на C ++, но более интегрированный, чем два других (доступно больше алгоритмов и структур данных). Eigen утверждает, что работает быстрее, чем реализации BLAS, описанные выше, но при этом не соответствует стандарту де-факто BLAS API. Эйген, похоже, не прилагает много усилий для параллельной реализации.
Armadillo - это библиотека LGPL3 для C ++. Он имеет привязку к LAPACK (библиотека, используемая numpy). Он использует рекурсивные шаблоны и метапрограммирование шаблонов, что является хорошим моментом (я не знаю, делают ли это и другие библиотеки?).
xtensor - это библиотека C ++, имеющая лицензию BSD. Он предлагает API C ++, очень похожий на API NumPy. См. Https://xtensor.readthedocs.io/en/latest/numpy.html для шпаргалки.
Эти альтернативы действительно хороши, если вы просто хотите получить структуры данных и базовую линейную алгебру. В зависимости от вашего вкуса в отношении стиля, лицензии или проблем системного администратора (установка больших библиотек, таких как LAPACK, может быть сложной), вы можете выбрать ту, которая лучше всего соответствует вашим потребностям.
источник
a[:4,::-1,:,19] = b[None,-5:,None]
илиa[a>5]=0
и подобные, а также имеющие огромный набор массивов и манипуляции индекса доступных функций. Я очень надеюсь, что кто-нибудь когда-нибудь сделает что-то подобное для C ++.a.colRange(4,7).rowRange(4,8)
дляa[4:7,4,8]
) и маска условий (a.setTo(cv::Scalar(0), a>5)
дляa[a>5]=0
)Попробуйте xtensor . (См. Шпаргалку от NumPy к Xtensor ).
xtensor - это библиотека C ++, предназначенная для численного анализа с многомерными выражениями массивов.
xtensor обеспечивает
пример
Инициализируйте двумерный массив и вычислите сумму одной из его строк и одномерного массива.
#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;
Выходы
{7, 11, 14}
Инициализируйте одномерный массив и измените его форму на месте.
#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;
Выходы
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
источник
DyND разработан как NumPy-подобная библиотека для C ++. Такие вещи, как трансляция, арифметические операторы и нарезка, работают нормально. С другой стороны, это все еще очень экспериментальная и многие функции еще не были реализованы.
Вот простая реализация алгоритма де Кастельжау на C ++ с использованием массивов DyND:
#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; }
Некоторое время назад я написал сообщение в блоге с большим количеством примеров и параллельным сравнением синтаксиса для Fortran 90, DyND в C ++ и NumPy в Python.
Отказ от ответственности: я один из текущих разработчиков DyND.
источник
Eigen - хорошая библиотека линейной алгебры.
http://eigen.tuxfamily.org/index.php?title=Main_Page
Его довольно легко установить, поскольку это библиотека только для заголовков. Он полагается на шаблон для создания хорошо оптимизированного кода. Он автоматически векторизует матричные операции.
Он также полностью поддерживает операции с коэффициентами, такие как, например, «умножение на элемент» между двумя матрицами. Это то, что вам нужно?
источник
Blitz ++ поддерживает массивы с произвольным количеством осей, тогда как Armadillo поддерживает до трех (векторы, матрицы и кубы). Eigen поддерживает только векторы и матрицы (не кубы). Обратной стороной является то, что Blitz ++ не имеет функций линейной алгебры, кроме базовых операций на входе и тензорных сокращений. Кажется, что некоторое время назад разработка замедлилась, но, возможно, это только потому, что библиотека делает то, что делает, и не нужно вносить много изменений.
источник
xtensor хорош, но в итоге я сам написал мини-библиотеку в виде игрушечного проекта на C ++ 20, стараясь при этом сделать интерфейс максимально простым. Вот он: https://github.com/gbalduzz/NDArray
Пример кода:
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]]
В нем пока нет причудливых арифметических операторов, объединяющих несколько операций вместе, новы можете транслировать произвольные лямбды на набор тензоров той же формы или использовать арифметические операторы с отложенным вычислением.Дайте мне знать, что вы думаете об интерфейсе и как он соотносится с другими вариантами, и если есть надежда, какие операции вы хотели бы реализовать.
Бесплатная лицензия и никакой зависимости!
Дополнение: мне удалось правильно скомпилировать и запустить xtensor, и в результате моя библиотека стала значительно быстрее при повторении представлений (от 2 до 3X).
источник
VIGRA содержит хорошую реализацию N-мерного массива:
http://ukoethe.github.io/vigra/doc/vigra/Tutorial.html
Я широко им пользуюсь и считаю его очень простым и эффективным. Это также только заголовок, поэтому его очень легко интегрировать в среду разработки. Это самое близкое к использованию NumPy с точки зрения API.
Основным недостатком является то, что он не так широко используется, как другие, поэтому вы не найдете большой помощи в Интернете. Это, и у него неуклюжее название (попробуйте поискать!)
источник
Используйте LibTorch (интерфейс PyTorch для C ++) и будьте счастливы.
источник
Это старый вопрос. Все еще хотелось ответить. Мысль может помочь многим, особенно кодированию pydevs на C ++.
Если вы уже работали с python numpy, то NumCpp - отличный выбор. Он минималистичен по синтаксису и имеет те же функции и методы, что и py numpy.
Часть сравнения в readme doc тоже очень-очень классная.
nc::NdArray<int> arr = {{4, 2}, {9, 4}, {5, 6}}; arr.reshape(5, 3); arr.astype<double>();
источник
Eigen - это библиотека шаблонов для линейной алгебры (матрицы, векторы…). Это только заголовок и бесплатное использование (LGPL).
источник
Если вы хотите использовать многомерный массив (например, numpy) для обработки изображений или нейронной сети, вы можете использовать
OpenCV
cv::Mat
вместе с множеством алгоритмов обработки изображений. Если вы просто хотите использовать его ТОЛЬКО для матричных операций, вам просто нужно скомпилировать соответствующие модули opencv, чтобы уменьшить размер и иметь крошечную библиотеку OpenCV.cv::Mat
(Матрица) - это n-мерный массив, который можно использовать для хранения различных типов данных, таких как изображения RGB, HSV или в градациях серого, векторы с действительными или комплексными значениями, другие матрицы и т. Д.Коврик содержит следующую информацию:
width, height, type, channels, data, flags, datastart, dataend
и так далее.В нем есть несколько методов манипулирования матрицей. Бонус вы можете создать как на ядрах CUDA, так и на
cv::cuda::GpuMat
.Предположим, я хочу создать матрицу с 10 строками и 20 столбцами типа CV_32FC3:
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
БОНУС:
Скомпилируйте крошечную и компактную библиотеку opencv только для матричных операций. Один из способов похож на упомянутый в этой статье.
ИЛИ ЖЕ
скомпилируйте исходный код opencv, используя следующую команду cmake:
$ 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
Попробуйте этот пример:
#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; }
Скомпилируйте код с помощью следующей команды:
$ g++ -std=c++11 opencv_mat.cc -o opencv_mat `pkg-config --libs opencv` `pkg-config --cflags opencv`
Запускаем исполняемый файл:
$ ./opencv_mat OpenCV Version 3.4.2 My Mat : [0, 0, 0, 0; 0, 0, 0, 0]
источник
GSL велик, он делает все , что вы просите , и многое другое. Однако он распространяется под лицензией GPL.
источник
Хотя GLM разработан для простого взаимодействия с OpenGL и GLSL, это полнофункциональная математическая библиотека только для заголовков для C ++ с очень интуитивно понятным набором интерфейсов.
Он объявляет векторные и матричные типы, а также различные операции с ними.
Умножение двух матриц выполняется просто как (M1 * M2). Вычитание двух векторов (V1-V2).
Доступ к значениям, содержащимся в векторах или матрицах, также прост. Например, после объявления вектора vec3 можно получить доступ к его первому элементу с помощью vector.x. Проверить это.
источник