网站设计文稿,广州建筑信息平台,泉州网站建设案例,网站设计制作费用前言
推荐两个比较好的教程:
BLAS (Basic Linear Algebra Subprograms)
LAPACK for Windows
命名规范
BLAS基本线性代数子程序的函数命令都有一定规范#xff0c;便于记忆
character name mod ()
character
定义的是数据类型
s实数域#…前言
推荐两个比较好的教程:
BLAS (Basic Linear Algebra Subprograms)
LAPACK for Windows
命名规范
BLAS基本线性代数子程序的函数命令都有一定规范便于记忆
character name mod ()
character
定义的是数据类型
s实数域单精度c复数域单精度d实数域双精度z复数域双精度
也可结合起来比如sc代表实数域和复数域的单精度类型dz代表实数域和复数域的双精度类型。
name
针对BLAS level 1也就是向量与向量间的操作的时候
dot向量点乘rot向量旋转swap向量交换
针对BLAS level 2和3的情况也就是矩阵参数类型
ge一般矩阵gb一般带状矩阵sy对称矩阵sp对称矩阵(压缩存储)sb对称带状矩阵he埃尔米特矩阵 Hermitian matrixhp埃尔米特矩阵(压缩存储)hb埃尔米特带状矩阵tr三角矩阵tp三角矩阵(压缩存储)tb三角带状矩阵
mod
提供操作的额外信息三种Level情况
针对Level 1
c共轭向量u非共轭向量gGivens 旋转结构m修正 Givens 旋转mg修正 Givens 旋转结构
针对Level 2
mv矩阵-向量乘积sv求解具有一个未知向量的线性方程组r矩阵的一阶更新r2矩阵的二阶更新
针对Level 3
mm矩阵-矩阵乘积sm求解具有多个未知向量的线性方程组rk矩阵的k阶更新r2k矩阵的2k阶更新
函数实例
ddot 双精度、实数域向量-向量点乘cdotc复数域向量-向量点乘共轭scasum巨型向量元素和单精度实数域输出单精度复数域输入cdotu向量-向量点乘一般矩阵单精度sgemv矩阵-向量点乘一般矩阵单精度ztrmm矩阵-矩阵乘法三角矩阵双精度复数域
C接口的调用方法
C接口相对于Fortran有一个优势就是可以指定是行优先还是列优先。调用方法就是在正常的命令规范前面加个前缀cblas_。对于复数函数?dotc和?dotu还需要加一个后缀_sub通过指针返回复数结果作为后一个参数添加进来。
使用CALBAS需要遵循一些规则
输入参数需要使用const修饰非复数标量输入参数直接使用值传递复数标量参数使用void指针传递矩阵参数使用地址传递BLAS类型参数使用合适的枚举类型代替Level 2和3中有一个CLABS_LAYOUT类型的额外参数作为第一个输入参数。这个参数指定二维数组是行优先CblasRowMajor还是列优先CblasColMajor
定义的枚举类型:
enum CBLAS_LAYOUT {
CblasRowMajor101, /* row-major arrays */
CblasColMajor102}; /* column-major arrays */
enum CBLAS_TRANSPOSE {
CblasNoTrans111, /* transN */
CblasTrans112, /* transT */
CblasConjTrans113}; /* transC */
enum CBLAS_UPLO {
CblasUpper121, /* uplo U */
CblasLower122}; /* uplo L */
enum CBLAS_DIAG {
CblasNonUnit131, /* diag N */
CblasUnit132}; /* diag U */
enum CBLAS_SIDE {
CblasLeft141, /* side L */
CblasRight142}; /* side R */
矩阵存储方案
三种存储方案
全部存储比如将矩阵AA存储到二维数组aa中矩阵元素AijA_{ij}以列优先的方式存储到a[ij∗lda]a[i+j*lda]中或者以行优先的形式存储到a[ji∗lda]a[j+i*lda]中。这里的lda就是数组的引导维度。压缩存储用于存储对称阵埃尔米特矩阵三角矩阵。对于列优先的布局上三角和下三角按照列存储到一个一维数组或者按照行优先的布局上三角和下三角按行存储到一个一维数组中。带状存储带状矩阵被压缩存储到一个二维数组中。对于列优先布局矩阵的列被存储到对应的数组列中矩阵对角部分被存储到数组的特殊行中。对于行优先的布局矩阵的行被存储到对应数组的行中矩阵对角部分被存储到数组的指定行中。
行优先与列优先
Fortran中以列优先的方式存储二维数组在C中需要数组为行优先的格式这是C的约定。讲道理的话这句话应该是这样写但是官方文档给出的英文是 The BLAS routines follow the Fortran convention of storing two-dimensional arrays using column-major layout. When calling BLAS routines from C, remember that they require arrays to be in column-major format, not the row-major format that is the convention for C. Unless otherwise specified, the psuedo-code examples for the BLAS routines illustrate matrices stored using column-major layout. 这里却写着是按照列存储的。但是在Intel® Math Kernel Library Getting Started Tutorial: Using the Intel® Math Kernel Library for Matrix Multiplication中的实例却是这样 代码是 这个for循环明显是将一行一行的赋值说明连续存储的单元是行中相邻的元素。但是后面的英文又是 The one-dimensional arrays in the exercises store the matrices by placing the elements of each column in successive cells of the arrays. 意思是联系中的以为数组是将每行列的元素放入到数组单元中。代码明明是每行的元素放入到其中。这到底是按行存储还是按列存储两篇参考博客介绍行列存储的区别 行优先和列优先的问题,矩阵存储的两种方式——行优先与列优先。个人感觉姑且认为是按行存储的吧毕竟代码是这样写的虽然与文字不一致。如果有同学有何见解希望在评论区讨论讨论^_^
Level 1所有函数
所有函数概览
函数名缺失部分描述cblas_?asums, d, sc, dz向量和cblas_?axpys, d, c, z标量-向量乘积cblas_?copys, d, c, z拷贝向量cblas_?dots,d点乘cblas_?sdotsd,d双精度点乘cblas_?dotcc,z共轭点乘cblas_?dotuc,z非共轭点乘cblas_?nrm2s,d,sc,dz向量2范数cblas_?rots,d,cs,zd绕点旋转cblas_?rotgs,d,c,z生成点的Givens旋转cblas_?rotms,d点的修正Givens旋转cblas_?rotmgs,d生成点的修正Givens旋转cblas_?scals, d, c, z, cs, zd向量-标量乘法cblas_?swaps, d, c, z向量-向量交换cblas_i?amaxs, d, c, z绝对值最大元素位置cblas_i?amins, d, c, z绝对值最小元素位置cblas_?cabs1s,d辅助函数计算单精度或者双精度复数的绝对值
cblas_?asum
作用计算向量元素和定义函数
float cblas_sasum (const MKL_INT n, const float *x, const MKL_INT incx);
float cblas_scasum (const MKL_INT n, const void *x, const MKL_INT incx);
double cblas_dasum (const MKL_INT n, const double *x, const MKL_INT incx);
double cblas_dzasum (const MKL_INT n, const void *x, const MKL_INT incx);
运算 计算实数向量的元素和或者计算复数向量的实部以及虚部的和 res|Re(x1)||Im(x1)||Re(x2||Im(x2)|⋯|Re(xn)||Im(xn)|res=|Re (x_1)|+|Im(x_1)|+|Re (x_2|+|Im(x_2)|+\cdots+|Re (x_n)|+|Im(x_n)|输入参数 nn : 向量的元素个数xx : 数组大小至少是(1(n−1)∗abs(incx))(1+(n-1)*abs(incx)) incxincx : 指定索引向量xx的增量
返回值:向量所有元素的和
cblas_?axpy
作用 : 计算向量-标量的积,然后加到结果上
定义函数
void cblas_saxpy (const MKL_INT n, const float a, const float *x, const MKL_INT incx, float *y, const MKL_INT incy);
void cblas_daxpy (const MKL_INT n, const double a, const double *x, const MKL_INT incx, double *y, const MKL_INT incy);
void cblas_caxpy (const MKL_INT n, const void *a, const void *x, const MKL_INT incx, void *y, const MKL_INT incy);
void cblas_zaxpy (const MKL_INT n, const void *a, const void *x, const MKL_INT incx, void *y, const MKL_INT incy);
运算
向量与向量之间的操作
y:=a∗x+y
y:=a*x+y输入参数 nn : 指定向量x,yx,y的元素个数 aa : 标量aa xx : 数组,大小至少是(1+(n−1)∗abs(incx))(1+(n-1)*abs(incx)) incxincx : 指定索引向量xx的增量yy : 数组大小至少是(1(n−1)∗abs(incy))(1+(n-1)*abs(incy)) incyincy : 指定索引向量yy的增量
返回值 : 最终更新得到的向量yy cblas_?copy 作用 : 拷贝一个向量到另一个向量定义函数 void cblas_scopy (const MKL_INT n, const float *x, const MKL_INT incx, float *y, const MKL_INT incy);
void cblas_dcopy (const MKL_INT n, const double *x, const MKL_INT incx, double *y, const MKL_INT incy);
void cblas_ccopy (const MKL_INT n, const void *x, const MKL_INT incx, void *y, const MKL_INT incy);
void cblas_zcopy (const MKL_INT n, const void *x, const MKL_INT incx, void *y, const MKL_INT incy);运算 拷贝向量 yxy=x输入参数 nn : 指定向量x,yx,y的元素个数 xx : 数组,大小至少是(1+(n−1)∗abs(incx))(1+(n-1)*abs(incx)) incxincx : 指定索引向量xx的增量yy : 数组大小至少是(1(n−1)∗abs(incy))(1+(n-1)*abs(incy)) incyincy : 指定索引向量yy的增量
返回值 : 当nn是正数的时候向量xx的拷贝被返回,否则参数不变。
cblas_?dot
作用 : 计算向量-向量的点乘
定义函数float cblas_sdot (const MKL_INT n, const float *x, const MKL_INT incx, const float *y, const MKL_INT incy);
double cblas_ddot (const MKL_INT n, const double *x, const MKL_INT incx, const double *y, const MKL_INT incy);
运算 :
res=∑i=1nxi∗yires=\sum_{i=1}^nx_i*y_i输入参数 n,x,incx,y,incyn,x,incx,y,incy分别代表元素个数数组xx,数组xx的索引增量数组yy,数组yy的索引增量返回值 : 返回两个向量的点乘如果n0n返回0 cblas_?sdot 作用 : 计算双精度向量-向量的点乘定义函数 float cblas_sdsdot (const MKL_INT n, const float sb, const float *sx, const MKL_INT incx, const float *sy, const MKL_INT incy);
double cblas_dsdot (const MKL_INT n, const float *sx, const MKL_INT incx, const float *sy, const MKL_INT incy);运算 ?sdot计算的是两个双精度向量的内积(点积)中间结果的累积是双精度的但是sdsdot返回的结果是单精度的使用dsdot可以输出双精度的结果。其中sdsdot为点积结果加一个标量值sb输入参数 nn : 输入向量xx和yy的维度sbsb : 内积的单精度缩放值(仅针对sdsdot) sx,sysx,sy : 数组包含单精度输入向量 incx,incyincx,incy : 两个数组的索引增量返回值 : 当nn为正的时候,返回两个数组的点乘(sdsdot结果加一个标量sb);若n≤0n\leq0对于sdsdot返回sbsb对于dsdot返回0 cblas_?dotc 作用 : 计算一个共轭向量与另一个向量的点积定义函数 void cblas_cdotc_sub (const MKL_INT n, const void *x, const MKL_INT incx, const void *y, const MKL_INT incy, void *dotc);
void cblas_zdotc_sub (const MKL_INT n, const void *x, const MKL_INT incx, const void *y, const MKL_INT incy, void *dotc);运算 res∑i1nconjg(xi)∗yires=\sum_{i=1}^n conjg(x_i)*y_i输入参数 n,x,incx,y,incyn,x,incx,y,incy分别代表元素个数数组xx及其索引增量,数组yy及其增量输出 : 如果n0n>0输出共轭向量xx与非共轭向量yy的点乘否则返回0 cblas_?dotu 作用 : 计算复数域的向量-向量的点积定义函数 void cblas_cdotu_sub (const MKL_INT n, const void *x, const MKL_INT incx, const void *y, const MKL_INT incy, void *dotu);
void cblas_zdotu_sub (const MKL_INT n, const void *x, const MKL_INT incx, const void *y, const MKL_INT incy, void *dotu);运算 res∑i1nxi∗yires=\sum_{i=1}^n x_i*y_i 其中xix_i和yiy_i分别是复数向量xx和yy的元素输入参数 : 同上输出参数 : 如果n0n>0返回点积否则返回0 cblas_?nrm2 作用 : 计算一个向量的欧几里得范数(Euclidean norm)定义函数 float cblas_snrm2 (const MKL_INT n, const float *x, const MKL_INT incx);
double cblas_dnrm2 (const MKL_INT n, const double *x, const MKL_INT incx);
float cblas_scnrm2 (const MKL_INT n, const void *x, const MKL_INT incx);
double cblas_dznrm2 (const MKL_INT n, const void *x, const MKL_INT incx);运算 res||x||res=||x||输入参数 : 元素个数数组索引增量返回值 : 向量xx的欧几里得范数
cblas_?rot
作用 : 平面上绕点旋转
定义函数void cblas_srot (const MKL_INT n, float *x, const MKL_INT incx, float *y, const MKL_INT incy, const float c, const float s);
void cblas_drot (const MKL_INT n, double *x, const MKL_INT incx, double *y, const MKL_INT incy, const double c, const double s);
void cblas_csrot (const MKL_INT n, void *x, const MKL_INT incx, void *y, const MKL_INT incy, const float c, const float s);
void cblas_zdrot (const MKL_INT n, void *x, const MKL_INT incx, void *y, const MKL_INT incy, const double c, const double s);
运算通俗写法
[xi,yi]=[xi,yi][cs−sc][x_i,y_i]=[x_i,y_i]\left[\begin{matrix}cc∗xis∗yiyic∗yi−s∗xix_i = c*x_i + s*y_i\\y_i = c*y_i - s*x_i输入参数 : 元素个数两个向量对应的索引增量c,sc,s表示所绕点的坐标标量输出参数 : xx的每个元素被c∗x+s∗yc*x+s*y代替yy的每个元素被c∗y−s∗xc*y-s*x代替 cblas_?rotg 作用 : 计算Givens旋转参数定义函数 void cblas_srotg (float *a, float *b, float *c, float *s);
void cblas_drotg (double *a, double *b, double *c, double *s);
void cblas_crotg (void *a, const void *b, float *c, void *s);
void cblas_zrotg (void *a, const void *b, double *c, void *s);运算 给定一个点的笛卡尔(Cartesian)坐标(a,b)(a,b),返回参数c,s,r,zc,s,r,z对应Givens旋转c,sc,s对应的是酉阵(unitary matrix)类似于 [c−ssc][ab][r0]\begin{bmatrix}c|b||a|>|b|,那么zsz=s否则如果c≠0c\neq 0,那么z1cz=\frac{1}{c}否则z1z=1输入参数 : a,ba,b分别提供点pp的横xx坐标和纵yy坐标
输出参数 : Givens的四个参数
cblas_?rotm
作用 : 修正绕平面是一点的Givens旋转
定义函数void cblas_srotm (const MKL_INT n, float *x, const MKL_INT incx, float *y, const MKL_INT incy, const float *param);
void cblas_drotm (const MKL_INT n, double *x, const MKL_INT incx, double *y, const MKL_INT incy, const double *param);
运算给定两个向量x,yx,y这些向量的每个元素都会被替代为 [xiyi]H[xiyi]\begin{bmatrix}x_i\\y_i\end{bmatrix}=H\begin{bmatrix}x_i\\y_i\end{bmatrix} 其中i1⋯ni=1\cdots nH是修正Givens旋转矩阵值存储在parm[1]parm[1]至parm[4]parm[4]中输入参数 n,x,incx,y,incy,n,x,incx,y,incy,分别表示元素个数两个向量对应增量索引 param : 包含五个参数param[0]param[0]代表切换标志param[1−4]param[1- 4]均包含h11,h12,h21,h22h_{11},h_{12},h_{21},h_{22}分别对应数组HH的成分,依据标识符,可以得到如下数组HH flag−1.0:H[h11h21h12h22]flag0.0:H[1.0h21h121.0]flag1.0:H[h11−1.01.0h22]flag−2.0:H[1.00.00.01.0]flag = -1.0: H =\begin{bmatrix}h_{11} 矩阵HH中的−0.1,−1.0,0.0-0.1,-1.0,0.0可以由标志指定无需在向量中写出来输出 : xx的每一个向量被h11∗x[i]+h12∗y[i]h_{11}*x[i] + h_{12}*y[i] 替换yy的每一个向量被h21∗x[i]+h22∗y[i]h_{21}*x[i] + h_{22}*y[i] 替换 cblas_?rotmg 作用 : 计算修正Givens旋转的参数定义函数 void cblas_srotmg (float *d1, float *d2, float *x1, const float y1, float *param);
void cblas_drotmg (double *d1, double *d2, double *x1, const double y1, double *param);运算 给定输入向量的笛卡尔坐标(x1,y1)(x_1,y_1),计算将结果向量的y置零时候计算得到的Givens旋转矩阵HH
[x10]=H[x1d1−−√y1d2−−√]\begin{bmatrix}x_1\\0\end{bmatrix}=H\begin{bmatrix}x_1\sqrt{d_1}\\y_1\sqrt{d_2}\end{bmatrix}输入参数 d1d1代表向量的xx轴缩放因子,d2d2代表向量的y轴缩放因子,x1,y1x1,y1是输入向量的横纵坐标输出 d1d1是更新矩阵的第一对角元 d2d2是更新矩阵的第二对角元 x1x1是缩放之前旋转向量的x坐标 paramparam同上cblas_?rotmg的输入parmaparma一样 cblas_?scal 作用 : 计算向量和标量的乘积定义函数 void cblas_sscal (const MKL_INT n, const float a, float *x, const MKL_INT incx);
void cblas_dscal (const MKL_INT n, const double a, double *x, const MKL_INT incx);
void cblas_cscal (const MKL_INT n, const void *a, void *x, const MKL_INT incx);
void cblas_zscal (const MKL_INT n, const void *a, void *x, const MKL_INT incx);
void cblas_csscal (const MKL_INT n, const float a, void *x, const MKL_INT incx);
void cblas_zdscal (const MKL_INT n, const double a, void *x, const MKL_INT incx);运算 xa∗xx=a*x输入参数 nn向量的元素个数,aa标量xx数组,incxincx向量x的索引增量输出 : 更新后的向量xx
cblas_?swap
作用 : 交换向量值
定义函数void cblas_sswap (const MKL_INT n, float *x, const MKL_INT incx, float *y, const MKL_INT incy);
void cblas_dswap (const MKL_INT n, double *x, const MKL_INT incx, double *y, const MKL_INT incy);
void cblas_cswap (const MKL_INT n, void *x, const MKL_INT incx, void *y, const MKL_INT incy);
void cblas_zswap (const MKL_INT n, void *x, const MKL_INT incx, void *y, const MKL_INT incy);
计算:交换向量xx和yy,互相代替元素值
输入参数 : 正常的五个输入,元素个数,数组,增量索引
输出 : 交换后的向量x,yx,y cblas_i?amax 作用 : 找到绝对值最大的元素的索引定义函数 CBLAS_INDEX cblas_isamax (const MKL_INT n, const float *x, const MKL_INT incx);
CBLAS_INDEX cblas_idamax (const MKL_INT n, const double *x, const MKL_INT incx);
CBLAS_INDEX cblas_icamax (const MKL_INT n, const void *x, const MKL_INT incx);
CBLAS_INDEX cblas_izamax (const MKL_INT n, const void *x, const MKL_INT incx);计算 : 给定向量xx,函数i?amax返回实数域中绝对值最大的向量元素x[i]x[i]的位置或者返回复数域|Re(x[i])||Im(x[i])||Re(x[i])|+|Im(x[i])|和的最大值 如果nn非正,则返回如果向量中有好几个位置的值等于最大元素,第一个位置将被返回
输入参数 : n,x,incxn,x,incx分别代表向量元素个数数组索引增量返回值 : 返回最大值元素的位置比如x[index−1]x[index-1]具有最大的绝对值 cblas_i?amin 作用 : 返回最小值的位置定义函数 CBLAS_INDEX cblas_isamin (const MKL_INT n, const float *x, const MKL_INT incx);
CBLAS_INDEX cblas_idamin (const MKL_INT n, const double *x, const MKL_INT incx);
CBLAS_INDEX cblas_icamin (const MKL_INT n, const void *x, const MKL_INT incx);
CBLAS_INDEX cblas_izamin (const MKL_INT n, const void *x, const MKL_INT incx);计算 : i?amin返回的是向量的最小绝对值的位置。与i?amax类似输入参数: 同i?amax返回值: 绝对值最小元素位置的索引比如x[index−1]x[index-1] 具有最小的绝对值 cblas_?cabs1 作用: 计算复数的绝对值是一个辅助函数用于辅助其它函数的实现定义函数 float cblas_scabs1 (const void *z);
double cblas_dcabs1 (const void *z);计算 res|Re(z)||Im(z)|res=|Re(z)|+|Im(z)|输入: 标量zz
返回值: 复数zz的绝对值