python 编译后的包,打包备份
在没有网络的情况下非常适合从一个已经安装包的电脑上拷贝包到另一个没有安装包的电脑上。 1、进入第三方库安装的路径的文件夹。\site-packages 2、找到需要的包复制即可。注意一个库的包有两个文件,要同时复制。 3、将包移动到另一台电脑上的\site-packages 粘贴即可使用。
注意: 有些需要编译的包,可能会多一个编译后的 so 的库文件。这个也要打包进去。
在没有网络的情况下非常适合从一个已经安装包的电脑上拷贝包到另一个没有安装包的电脑上。 1、进入第三方库安装的路径的文件夹。\site-packages 2、找到需要的包复制即可。注意一个库的包有两个文件,要同时复制。 3、将包移动到另一台电脑上的\site-packages 粘贴即可使用。
注意: 有些需要编译的包,可能会多一个编译后的 so 的库文件。这个也要打包进去。
kernel 通过 drm 向 hdmi 设备进行显示,资料可以参考: https://zhuanlan.zhihu.com/p/59784377 https://zhuanlan.zhihu.com/p/60504398 https://dri.freedesktop.org/docs/drm/gpu/drm-kms.html?highlight=writeback https://www.kernel.org/doc/html/v4.17/gpu/drm-kms.html https://blog.csdn.net/u014674293/article/details/105774238 https://www.cnblogs.com/mao0504/p/5619107.html https://blog.csdn.net/hexiaolong2009/article/details/89810355
调整 hdmi 分辨率: https://forum.khadas.com/t/hdmi-resolutions-testing/618/6
buildroot 英文手册 nightly: http://nightly.buildroot.org/manual.html#getting-buildroot stable: https://buildroot.org/downloads/manual/manual.html#_getting_started
中文: https://blog.csdn.net/haimo_free/article/details/107677695 http://www.cxyzjd.com/article/haimo_free/107677695
驱动开发: https://blog.csdn.net/a568713197/article/details/103069325
在算法中运用迭代器时,很可能会用到其相应型别,什么是相应型别?迭代器所指之物的型别便是其中之一。C++ 有函数模版推导机制,例如:
template<class I ,class T>
void func_imp1(I iter, T t)
{
T tmp; // 这里解决了问题,T就是迭代器所指之物的型别,本例为int
};
template <class I>
inline void func(I iter)
{
func_imp1(iter ,*iter); // func 的工作全部移往 func_imp1
}
int main()
{
int i;
func(&i);
}
迭代器所指对象的型别。成为该迭代器的 value type。上述的参数型别推导虽然可用于value_type,但是当value type 必须用于函数的传回值,就束手无策了,毕竟函数的 “template 参数推导机制” 推而导之的只是参数,无法推导函数的返回值型别。
其他方法如声明内嵌型别似乎是个好主意,例如:
template<class T>
struct MyIter{
typedef T value_type; // 内嵌型别声明
T* ptr;
MyIter (T* p=0): ptr(p){ }
T& operator*() const {return *ptr;}
//....
};
template<class I>
typename I:: value_type
func(I ite)
{ return *ite; }
//...
MyIter<int>ite(new int(8));
cout<<func(ite);
注意:并不是所有的迭代器都是 class type。原生指针就不是!如果不是 class type,就无法为它定义内嵌型别。但是STL绝对必须接受原生指针作为一种迭代器,因此需要一种方法将上述的一般化概念针对特定情况做特殊化处理。
偏特化就可以做到,如下面一个class template:
template<typename T>
class C { ... }; //这个泛化版本允许T为任何型别
很容易接受它有一个形式如下的 partial specialization:
template<typename T>
class C<T*>{ ... }; //这个特化版本仅适用于“T为原生指针”的情况
// “T为原生指针” 便是 “T为任何型别” 的一个更进一步的条件限制
下面这个 class template 专门用来 “萃取”迭代器的特性,而 value type正是迭代器的特性之一:
template<class I>
struct iterator_traits{
typedef typename I::value_type value_type;
};
这个所谓的 traits,其意义是,如果 I 定义有自己的 value_type,那么通过这个 traits 的作用,萃取出来的 value_type 就是 I:: value_type.换句换说,如果I定义有自己的 value type,先前那个 func() 可以改写成这样:
template<class I>
typename iterator_traits<I>::value_type
func(I ite)
{ return *ite; }
但是除了多一层间接性,又带来什么好处呢?好处是 traits 可以拥有特化版本。现在,我们令 iterator_traits 拥有一个 partial specializations 如下:
template<class T>
struct iterator_traits<T*>{ //偏特化版本------迭代器是个原生指针
typedef T value_type;
};
最常用到的迭代器的相应型别有五种:value type,difference type,pointer,reference,iterator,iterator catagoly。如果你希望你所开发的容器能与STL水乳交融,一定要为你的容器的迭代器定义这五种相应型别。特性萃取机 traits 会很忠实的提取出来:
template<class I>
struct iterator_traits{
typedef typename I:: iterator_category iterator_category;
typedef typename I:: value_type value_type;
typedef typename I:: difference_type difference_type;
typedef typename I:: pointer pointer;
typedef typename I:: reference reference;
};
本篇适合不熟悉这两个函数的读者
以前在使用stl的过程中发现bind1st和bind2nd这两个函数,当时不太理解什么意思,今天在网上查了一下相关资料发现竟然很简单,下面我就具体解释一下他们的用法。
bind1st和bind2nd函数用于将一个二元算子(binary functor,bf)转换成一元算子(unary functor,uf)。为了达到这个目的,它们需要两个参数:要转换的bf和一个值(v)。
可能这么解释以后大家还不是很清楚,那么就说点白话吧。我们在做比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数表示你程序里面的表达式要和k值去比较。上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。大家可能会注意到这里面没有=的比较,先别着急,后面将会说道如何实现=的比较。先举两个例子看看bind1st和bind2nd的用法。
int a[] = {1, 2, 100, 200};
std::vector< int> arr(a, a + 4);
// 移除所有小于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::less< int>(), 100)), arr.end());
这里的比较表达式相当于arr.value < 100
如果用bind1st则表达的意思就恰恰相反
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind1st( std::less< int>(), 100)), arr.end());
这里的表达式相当于100 < arr.value
当然为了实现删除大于100的元素你同样可以使用bind2nd
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::greater< int>(), 100)), arr.end());
前面说道=的比较,比如说x <= k怎么实现呢,std又提供了一个好东西not1,我们可以说 !(x > k) 和 x <= k是等价的,那么我们看看下面的表达式:
// 移除所有小于等于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());
说明:not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数
例子需要包含头文件
#include <vector>
#include <algorithm>
#include <functional>
pytorch 中的 softmax 函数功能和具体的 c++ 实现如下:
类似于 python 的 numpy 库的 c++ 实现 xtensor 学习记录。
安装 xtensor 之前需要先安装依赖 xtl, https://github.com/xtensor-stack/xtl https://github.com/xtensor-stack/xtensor
进入 xtl 源码目录运行命令:
cmake -DCMAKE_INSTALL_PREFIX=/usr
sudo make install
进入 xtensor 源码目录运行命令:
cmake -DCMAKE_INSTALL_PREFIX=/usr
sudo make install
工程目录下创建 compile.sh
#!/bin/bash
mkdir -p build
pushd build
cmake ..
make
make install
popd
相应的 CMakeLists 文件中添加:
set(CMAKE_CXX_STANDARD 14)
如果工程还涉及到 opencv,那么需要添加
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIBRARY_DIRS})
target_link_libraries(${name} ${OpenCV_LIBS})
如果工程中用到 cjsonobject,需要添加
include_directories("${PROJECT_SOURCE_DIR}/CJsonObject")
如果工程运行的时候,需要某些库文件,那么可以新建一个 run.sh,里面可以如下添加库,然后运行:
#!/bin/bash
export LD_LIBRARY_PATH=./tengine/linux-arm64-v8a/lib/
./build/install/bin/classification
最近需要把一些 python 版本的程序转为 c++ 的程序。 python 中使用了很多 numpy 的调用,于是就再找 c++ 的实现。 找了一圈下来,发现最适合的可能就是 xtensor。 github: https://github.com/xtensor-stack/xtensor 使用: https://xtensor.readthedocs.io/en/latest/numpy.html
The GNU Scientific Library is a GPL software written in C. Thus, it has a C-like allocation and way of programming (pointers, etc.). With the GSLwrap, you can have a C++ way of programming, while still using the GSL. GSL has a BLAS implementation, but you can use ATLAS instead of the default CBLAS, if you want even more performances.
The boost/uBLAS library is a BSL library, written in C++ and distributed as a boost package. It is a C++-way of implementing the BLAS standard. uBLAS comes with a few linear algebra functions, and there is an experimental binding to ATLAS.
eigen is a linear algebra library written in C++, distributed under the MPL2 license (starting from version 3.1.1) or LGPL3/GPL2 (older versions). It's a C++ way of programming, but more integrated than the two others (more algorithms and data structures are available). Eigen claim to be faster than the BLAS implementations above, while not following the de-facto standard BLAS API. Eigen does not seem to put a lot of effort on parallel implementation.
Armadillo is LGPL3 library for C++. It has binding for LAPACK (the library used by numpy). It uses recursive templates and template meta-programming, which is a good point (I don't know if other libraries are doing it also?).
xtensor is a C++ library that is BSD licensed. It offers A C++ API very similar to that of NumPy. See https://xtensor.readthedocs.io/en/latest/numpy.html for a cheat sheet.
参考: https://stackoverflow.com/questions/11169418/numpy-style-arrays-for-c https://github.com/dpilger26/NumCpp
np.array([127, 127, 127])
生成一个一维数组 [127, 127, 127]。参考: https://numpy.org/doc/stable/reference/generated/numpy.array.html
a = np.reshape(list(range(24)), (2, 3, 4))
reshape 的第二个参数是维度参数,比如这个是一个三维数组,行数 2 行,列数 3 行,每个单位 4 个元素。参考: https://numpy.org/doc/stable/reference/generated /numpy.reshape.html?highlight=reshape#numpy.reshape
image = np.transpose(image, [2, 0, 1])
矩阵转置,第二个参数是相应的维度变化。 原始的维度是 [0, 1, 2] 其他的都是需要转换的。比如这个 [2, 0, 1] 意思是 把 第三维的数据提取出来作为第一维的开头数据,第一维的数据提取出来放到第二维,第二维的数据放到第三维。arr = np.arange(16)
matrix = arr.reshape(2, 2, 4)
print("matrix: ", matrix)
matrix_4 = matrix.transpose((2, 0, 1))
print("matrix 4: ", matrix_4)
输出结果为
matrix: [ [ [ 0 1 2 3]
[ 4 5 6 7] ]
[ [ 8 9 10 11]
[12 13 14 15] ] ]
matrix 4: [ [ [ 0 4]
[ 8 12]]
[ [ 1 5]
[ 9 13] ]
[ [ 2 6]
[10 14] ]
[ [ 3 7]
[11 15] ] ]
参考: https://blog.csdn.net/u012762410/article/details/78912667
np.expand_dims(a, axis)
第二个参数表示具体再那个地方增加一个维度。import numpy as np
a = np.reshape(list(range(24)), (2, 3, 4))
a_new = np.expand_dims(a, axis=0)
print('a =', a)
print('a_new =', a_new)
print('a.shape = ', a.shape)
print('a_new.shape = ', a_new.shape)
a = [[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
a_new = [[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]]
a.shape = (2, 3, 4)
a_new.shape = (1, 2, 3, 4)
import numpy as np
a = np.reshape(list(range(24)), (2, 3, 4))
print('a =', a)
print('np.expand_dims(a, axis=1) =', np.expand_dims(a, axis=1))
print('np.expand_dims(a, axis=2) =', np.expand_dims(a, axis=2))
print('np.expand_dims(a, axis=3) =', np.expand_dims(a, axis=3))
print('a.shape = ', a.shape)
print('np.expand_dims(a, axis=1).shape =', np.expand_dims(a, axis=1).shape)
print('np.expand_dims(a, axis=2).shape =', np.expand_dims(a, axis=2).shape)
print('np.expand_dims(a, axis=3).shape =', np.expand_dims(a, axis=3).shape)
a = [[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
np.expand_dims(a, axis=1) = [[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]]
[[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]]
np.expand_dims(a, axis=2) = [[[[ 0 1 2 3]]
[[ 4 5 6 7]]
[[ 8 9 10 11]]]
[[[12 13 14 15]]
[[16 17 18 19]]
[[20 21 22 23]]]]
np.expand_dims(a, axis=3) = [[[[ 0]
[ 1]
[ 2]
[ 3]]
[[ 4]
[ 5]
[ 6]
[ 7]]
[[ 8]
[ 9]
[10]
[11]]]
[[[12]
[13]
[14]
[15]]
[[16]
[17]
[18]
[19]]
[[20]
[21]
[22]
[23]]]]
a.shape = (2, 3, 4)
np.expand_dims(a, axis=1).shape = (2, 1, 3, 4)
np.expand_dims(a, axis=2).shape = (2, 3, 1, 4)
np.expand_dims(a, axis=3).shape = (2, 3, 4, 1)
参考: https://blog.csdn.net/weixin_41560402/article/details/105289015
.astype(np.float32)
转换数据类型。参考: https://blog.csdn.net/qq_34638161/article/details/102853276
np.concatenate()
对数列或者矩阵进行合并。import numpy as np
a=[1,2,3]
b=[4,5,6]
np.concatenate((a,b),axis=0)
array([1, 2, 3, 4, 5, 6])
参考: https://www.jianshu.com/p/a094a954ff61
numpy -> list: array.tolist()
list -> numpy: numpy.array(list)
参考: https://www.cnblogs.com/WMT-Azura/p/11138084.html
参考数目: https://www.runoob.com/numpy/numpy-array-manipulation.html https://numpy.org/doc/stable/user/c-info.html https://numpy.org.cn/article/advanced/numpy_exercises_for_data_analysis.html#numpy%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E9%97%AE%E7%AD%94