版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/Tosonw/article/details/91860627
一、簡介
NumCpp:Python NumPy庫的一個Templatized Header Only C ++實現
NumCpp 是一個高性能的數學計算 C++ 庫,它提供了一個簡單的 Numpy/Matlab 類似的接口。
NumCpp中的主要數據結構是NdArray。它本質上是一個 2D 數組類,一維數組實現為1xN數組。還有一個DataCube類作為便利容器提供,用于存儲2D數組NdArray,但它通過簡單容器的用途有限。
地址 https://github.com/dpilger26/NumCpp
文檔地址 https://dpilger26.github.io/NumCpp/doxygen/html/index.html
二、使用
1.源碼
$ git clone https://github.com/dpilger26/NumCpp
源碼中的src文件夾下的文件能夠直接被項目使用:
# 拷貝到項目中
$ cp NumCpp/src/ /home/toson/project/pro1/
// 引用頭文件即可使用
#include"src/NumCpp.hpp"
三、程序
#include"NumCpp.hpp"
#include"boost/filesystem.hpp"
#include
int main()
{
??? // Containers
??? nc::NdArray
??? nc::NdArray
??? a1.reshape(2, 3);
??? auto a2 = a1.astype
??? // Initializers
??? auto a3 = nc::linspace
??? auto a4 = nc::arange
??? auto a5 = nc::eye
??? auto a6 = nc::zeros
??? auto a7 = nc::NdArray
??? auto a8 = nc::ones
??? auto a9 = nc::NdArray
??? auto a10 = nc::nans(3, 4);
??? auto a11 = nc::NdArray
??? auto a12 = nc::empty
??? auto a13 = nc::NdArray
??? // Slicing/Broadcasting
??? auto a14 = nc::Random
??? auto value = a14(2, 3);
??? auto slice = a14({ 2, 5 }, { 2, 5 });
??? auto rowSlice = a14(a14.rSlice(), 7);
??? auto values = a14[a14 > 50];
??? a14.putMask(a14 > 50, 666);
??? // Random
??? nc::Random<>::seed(666);
??? auto a15 = nc::Random
??? auto a16 = nc::Random
??? auto a17 = nc::Random
??? auto a18 = nc::Random
??? // Concatenation
??? auto a = nc::Random
??? auto b = nc::Random
??? auto c = nc::Random
??? auto a19 = nc::stack({ a, b, c }, nc::Axis::ROW);
??? auto a20 = nc::vstack({ a, b, c });
??? auto a21 = nc::hstack({ a, b, c });
??? auto a22 = nc::append(a, b, nc::Axis::COL);
??? // Diagonal, Traingular, and Flip
??? auto d = nc::Random
??? auto a23 = nc::diagonal(d);
??? auto a24 = nc::triu(a);
??? auto a25 = nc::tril(a);
??? auto a26 = nc::flip(d, nc::Axis::ROW);
??? auto a27 = nc::flipud(d);
??? auto a28 = nc::fliplr(d);
??? // iteration
??? for (auto it = a.begin(); it < a.end(); ++it)
??? {
??????? std::cout << *it << " ";
??? }
??? std::cout << std::endl;
??? for (auto& arrayValue : a)
??? {
??????? std::cout << arrayValue << " ";
??? }
??? std::cout << std::endl;
??? // Logical
??? auto a29 = nc::where(a > 5, a, b);
??? auto a30 = nc::any(a);
??? auto a31 = nc::all(a);
??? auto a32 = nc::logical_and(a, b);
??? auto a33 = nc::logical_or(a, b);
??? auto a34 = nc::isclose(a, b);
??? auto a35 = nc::allclose(a, b);
??? // Comparisons
??? auto a36 = nc::equal(a, b);
??? auto a37 = a == b;
??? auto a38 = nc::not_equal(a, b);
??? auto a39 = a != b;
??? auto a40 = nc::nonzero(a);
??? // Minimum, Maximum, Sorting
??? auto value1 = nc::min(a);
??? auto value2 = nc::max(a);
??? auto value3 = nc::argmin(a);
??? auto value4 = nc::argmax(a);
??? auto a41 = nc::sort(a, nc::Axis::ROW);
??? auto a42 = nc::argsort(a, nc::Axis::COL);
??? auto a43 = nc::unique(a);
??? auto a44 = nc::setdiff1d(a, b);
??? auto a45 = nc::diff(a);
??? // Reducers
??? auto value5 = nc::sum
??? auto a46 = nc::sum
??? auto value6 = nc::prod
??? auto a47 = nc::prod
??? auto value7 = nc::mean(a);
??? auto a48 = nc::mean(a, nc::Axis::ROW);
??? auto value8 = nc::count_nonzero(a);
??? auto a49 = nc::count_nonzero(a, nc::Axis::ROW);
??? // I/O
??? a.print();
??? std::cout << a << std::endl;
??? auto tempDir = boost::filesystem::temp_directory_path();
??? auto tempTxt = (tempDir / "temp.txt").string();
??? a.tofile(tempTxt, "\n");
??? auto a50 = nc::fromfile
??? auto tempBin = (tempDir / "temp.bin").string();
??? nc::dump(a, tempBin);
??? auto a51 = nc::load
??? // Mathematical Functions
??? // Basic Functions
??? auto a52 = nc::abs(a);
??? auto a53 = nc::sign(a);
??? auto a54 = nc::remainder(a, b);
??? auto a55 = nc::clip(a, 3, 8);
??? auto xp = nc::linspace
??? auto fp = nc::sin(xp);
??? auto x = nc::linspace
??? auto f = nc::interp(x, xp, fp);
??? // Exponential Functions
??? auto a56 = nc::exp(a);
??? auto a57 = nc::expm1(a);
??? auto a58 = nc::log(a);
??? auto a59 = nc::log1p(a);
??? // Power Functions
??? auto a60 = nc::power
??? auto a61 = nc::sqrt(a);
??? auto a62 = nc::square(a);
??? auto a63 = nc::cbrt(a);
??? // Trigonometric Functions
??? auto a64 = nc::sin(a);
??? auto a65 = nc::cos(a);
??? auto a66 = nc::tan(a);
??? // Hyperbolic Functions
??? auto a67 = nc::sinh(a);
??? auto a68 = nc::cosh(a);
??? auto a69 = nc::tanh(a);
??? // Classification Functions
??? auto a70 = nc::isnan(a.astype
??? //nc::isinf(a);
??? // Linear Algebra
??? auto a71 = nc::norm
??? auto a72 = nc::dot
??? auto a73 = nc::Random
??? auto a74 = nc::Random
??? auto a75 = nc::Random
??? auto value9 = nc::linalg::det(a73);
??? auto a76 = nc::linalg::inv(a73);
??? auto a77 = nc::linalg::lstsq(a74, a75);
??? auto a78 = nc::linalg::matrix_power
??? auto a79 = nc::linalg::multi_dot
??? nc::NdArray
??? nc::NdArray
??? nc::NdArray
??? nc::linalg::svd(a.astype
??? return 0;
}
四、如果有問題
1.遇到頭文件問題
fatal error: NumCpp/Types.hpp: No such file or directory
?#include"NumCpp/Types.hpp"
請檢查CMakeLists.txt中:include_directories()中包含路徑。
2.依賴問題
/usr/local/include/boost/math/special_functions/lanczos.hpp:104:25: note: use -std=gnu++11 or -fext-numeric-literals to enable more built-in suffixes
/usr/local/include/boost/math/special_functions/lanczos.hpp:105:25: error: unable to find numeric literal operator ‘operator""Q’
????????? static_cast
參照依賴項:
??? C ++標準: C ++ 11,C ++ 14 或 C ++ 17
??? 編譯器: VS 2017/2019,GCC 7.4.0 或 Clang 6.0
??? Boost版本: 1.68 或 1.70
檢查GCC版本
$ gcc -v
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)
檢查boost版本
$ dpkg -S /usr/include/boost/version.hpp
libboost1.68-dev:amd64: /usr/include/boost/version.hpp
附:boost編譯
下載boost1.68:https://dl.bintray.com/boostorg/release/1.68.0/source/
$ tar -zxvf boost_1_68_0.tar.gz
$ cd boost_1_68_0/
# 編譯
$ ./bootstrap.sh --with-libraries=all --with-toolset=gcc
# 安裝
$ ./b2 install --prefix=/usr
3. Linux編譯問題
note: use -std=gnu++11 or -fext-numeric-literals to enable more built-in suffixes
error: unable to find numeric literal operator ‘operator""Q’
static_cast
需要在項目中的CMake編譯選項中增加:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals")
In function `boost::system::generic_category()':
undefined reference to `boost::system::detail::generic_category_ncx()'
在CMake編譯時需要依賴庫:boost_system
五、運算效率
基于:Ubuntu 16.04LTS,Core-i7 8700,Clion
1.nc::dot
auto mel = nc::dot
//注:mel_basis為shape(80,1025),mag為shape(1025,109)
//我后來優化為使用opencv來實現的
cv::Mat cv_mel = cv_mel_basis * cv_mag;???? //2ms
2.nc::log10(nc::maximum(...))運算還將就,不過opencv更快
// to decibel?????????? //2ms
mel = nc::log10(nc::maximum(mel, nc::NdArray
mag = nc::log10(nc::maximum(mag, nc::NdArray
?? ?
//嘗試使用opencv來實現????? //0ms(<0.5ms)
cv::log(cv::max(cv_mel, 1e-5), cv_mel);
3.nc::pad()的實現與numpy不一樣:
numpy可以實現一維填充(一維數列),而numcpp會將每個維度都進行填充。
比如我想實現一維數列的填充,結果出來后成為了二維數列了。
并且無法完成reflect填充。
//注:ncbuffer的shape(1,43350)
auto ncbuffer_pad = nc::pad(ncbuffer, nc::uint16(pad_lenght), 0.0);
//nc::pad()會將二維也進行填充,成為2049*45398
我當初是自己寫循環實現的,后來使用opencv里的copyMakeBorder來完成reflect填充:
cv::copyMakeBorder(cv_padbuffer, cv_padbuffer, 0, 0, pad_lenght, pad_lenght, cv::BORDER_REFLECT_101);//cv::BORDER_REFLECT
這里發現opencv里copyMakeBorder的BORDER_REFLECT填充是這樣的:
例:fedcba|abcdefgh|hgfedcb
我要實現numpy里的reflect填充,它的效果是這樣的:
例:gfedcb|abcdefgh|gfedcba
所以應該使用BORDER_REFLECT_101。
4.其他。。。
————————————————
版權聲明:本文為CSDN博主「Tosonw」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Tosonw/article/details/91860627
評論
查看更多