目录
- 1 正常的wave表达式
- 1.1 矩阵创建
- 1.2 矩阵相加和乘以常数
- 2 MatrixXXX Operations
- 2.1 一般的(general)
- 2.2 本征值(eigenvalues),本征矢量(eigenvectors)和分离(decompositions)
- 2.3 线性方程(Linear equations)和最小平方(least squares)
- 3 MatrixOp
- 3.1 MatrixOp的常用数据形式
- 3.2 MatrixOp和wave的维度
- 3.3 MatrixOp操作符
- 3.4 MatrixOp用于乘法和缩放
- 3.5 MatrixOp用于数据重排和提取
- 3.6 MatrixOp的数据传递原则
- 3.7 MatrixOp的组合运算
- 3.8 MatrixOp对四元数(Quaternion)
- 小结:
大家好,今天给大家总结一下Igor中的矩阵运算。Igor中有三种基本的矩阵运算方式:正常的wave表达式、MatrixXXX操作、MatrixOP操作。本文中大部分例子是从用户手册中翻译过来的。
1 正常的wave表达式
这种方式只能进行最简单的矩阵创建、矩阵相加和乘以常数。
1.1 矩阵创建
实际上就是n维的数组(Igor中最多4维)。用大括号'{}'包含每一行的元素,行内/行之间用逗号','隔开。例如:
Make matA={{1,2,3},{4,5,6}}, matB={{7,8,9},{10,11,12}}
1.2 矩阵相加和乘以常数
matA = matA+0.01*matB
此时矩阵matA的新数值是:
2 MatrixXXX Operations
Igor中内置的大部分矩阵运算命令都是以Matrix开头,如矩阵相乘--MatrixMultiply。这些命令大部分都是用的LAPACK的库链接。除非特别声明,都支持实数和复数的运算、支持单精度和双精度。
这些命令的功能比较单一(下表),比如求本征值、逆矩阵等等。现在Igor用MatrixOp整合了这些命令,简化了语法,从而提高了使用效率。
2.1 一般的(general)
2.2 本征值(eigenvalues),本征矢量(eigenvectors)和分离(decompositions)
2.3 线性方程(Linear equations)和最小平方(least squares)
3 MatrixOp
常见的wave运算比如:
wave1=wave2+wave3
当右边的表达式变得复杂或者wave很大的时候,用MatrixOp可以极大的提高效率。使用时把MatrixOp放在表达式前方即可:
MatrixOp wave1=wave2+wave3
虽然表达式类似,但MatrixOp的行为很不相同:
- MatrixOp作用于纯的数组元素
- MatrixOp不支持x, y, z, p, q, r, 或s的索引方式
- MatrixOp会根据右侧表达式来确定目标wave的数据类型和大小
- MatrixOp是点对点的存储,因此最好目标数组不要出现在右侧表达式中
- MatrixOp不能调用用户自定义的函数
3.1 MatrixOp的常用数据形式
- 数字(literal number)
- 常量(numeric constant)
- 局部/全局变量(local/global variable)
- 数组(wave)
- 数组层(wave layer)
- 矩阵函数的返回结果(output from a MatrixOp function)
下边是例子:
Constant kConstant = 234
Function Demo()
// Literal number
MatrixOp/O dest = 123
// Constant
MatrixOp/O dest = kConstant
// Local Variable
Variable localVariable = 345
MatrixOp/O dest = localVariable
// Global Variable
Variable/G root:gVar = 456
NVAR globalVariable = root:gVar
MatrixOp/O dest = globalVariable
// Wave
Make/O/N=(3,3) mat = p + 10*q
MatrixOp/O tMat = mat^t
// Wave layer
Make/O/N=(3,3,3) w3D = p + 10*q + 100*r
MatrixOp/O layer1 = w3D[][][1]
// Output from a MatrixOp function
MatrixOp/O invMat = inv(mat)
End
MatrixOp只支持两种形式的wave子集:
- 单个数值scalars:wave1D[a], wave2D[a] [b], wave3D[a] [b] [c]
- 一个或多层Layers(2D的数组):wave3D [] [] [a] (3D数组中的第a层), wave3D[] [] [a, b](3D数组从a到b的一系列层), wave3D [] [] [a, b, c](3D数组从a到b,步进为c的一系列层)
不支持列(如:wave3D[] [1] [2])或者行(如:wave3D[1] [] [2])。
另外,用MatrixOp的时候不能两侧是同一个3D的wave:
MatrixOp/O wave3D=wave3D+3
而应该用:
MatrixOp/O newWave3D=wave3D+3
3.2 MatrixOp和wave的维度
MatrixOp最开始是为了优化对2D数组的操作,后来扩展到其他维度。
- 1D的wave被当作只有一列的矩阵。
- 3D和4D的wave被看作一系列的层.
因此赋值的时候也是一层一层地进行。例如:
Make/O/N=(4,5) wave2 = q
Make/O/N=(4,5,6) wave3 = r
MatrixOp/O wave1 = wave2 * wave3
得到的wave1是一个(4,5,6)的3D wave。其每一层都是对应的wave3的层与wave2元素对元素相乘的结果。
有一些操作对两个数组有维度要求,比如,
- 矩阵相乘(wave2 x wave3)要求wave2的列数等于wave3的行数。
- 常规相乘(wave4*wave5)要求两者的列数和行数都匹配。
make/o/n=(3,4) wave2
make/o/n=(4,5) wave3
MatrixOp/O wave1=wave2 x wave3
make/o/n=(3,5) wave4, wave5
MatrixOp/O wave6=wave4*wave5
3.3 MatrixOp操作符
MatrixOp提供了很多操作符(见手册MatrixOp部分)。下边是一些常用操作符的介绍:
- MatrixOp不支持组合操作符,比如'+='
- Matrix中的'+', '-', '*', '/'基本和常规运算一致,但是遇到'-', '/',并且同时有matrix和scalar的情况,Igor只支持先运算Matrix再运算scalar
Make/o wave2=1
variable var2=7
MatrixOp/O wave1=wave2-var1 //可以
MatrixOp/O wave1=var1-wave2 //不可以
MatrixOp/o wave1=var/wave2 //不可以
- 逻辑运算符&&和||只适合实数数据类型
- 矩阵转置'^t'和Hermitian转置'^h'紧贴在作用的wave后方:
MatrixOp/O wave1=wave2^t
运算优先级:
3.4 MatrixOp用于乘法和缩放
- 矩阵-标量相乘
MatrixOp/O wave1=wave2*scalar
- 标量除以矩阵:
MatrixOp/o wave1=scalar * rec(wave2)
- wave-wave相乘用**句号'.'**表示:
MatrixOp/O wave1=wave2 . wave3 //'.'前后的空格可以省略
- 矩阵-矩阵相乘用**'x'**表示:
MatrixOp/O wave1=wave2 x wave3 //‘x'前后的空格不可省略
3.5 MatrixOp用于数据重排和提取
// Extract scalar from point a of the wave
MatrixOp destWave = wave1d[a]
// Extract scalar from element a,b of the wave
MatrixOp destWave = wave2d[a][b]
// Extract scalar from element a,b,c of the wave
MatrixOp destWave = wave3d[a][b][c]
// Extract layer a from the 3D wave
MatrixOp destWave = wave3d[][][a]
MatrixOp destWave = wave3d[][][a,b]
MatrixOp destWave = wave3d[][][a,b,c]
如果需要对行(Rows)、列(Columns)、层(Layers)或者块(Chunks)循环操作,可以用MatrixOp的函数row, col, layer和chunk。可以用getDiag提取矩阵的对角元。可以用Subrange提取多个row, column。
3.6 MatrixOp的数据传递原则
- MatrixOp产生的数据类型根据实际情况。对复数运算特别方便, 输出的数组可以自动判断,不用特意声明,比如:
Make/O/C wave2, wave3
Make/O wave4
MatrixOp/O wave1=wave2*wave3*wave4 //wave1是复数的
MatrixOp/O wave1=abs(wave2*wave3)*wave4 //wave1是实数的
3.7 MatrixOp的组合运算
MatrixOp中的大部分函数满足组合使用。比如:
MatrixOp/O wave1=sum(abs(wave2-wave3))
这对变换和过滤操作尤其方便:
MatrixOp/O wave1=IFFT(FFT(wave1,2)*filterwave, 3)
3.8 MatrixOp对四元数(Quaternion)
四元数{w, x, y, z}包含一个振幅w和三个矢量元x, y, z,其中
a, b, c, d是实数,i, j, k是四元数的基本单位。
四元数通常用于表示三维图形的旋转。**Igor Pro8中通过MatrixOp加入对四元数的支持。**四元数的运算有其自己的法则,比如,相乘不满足交换律(ij不等于ji)。
这里可以用MatrxOp创建和相乘,比如:
Function QuaternionMultiplicationDemo()
// Create waves containing the w, x, y, and z values of quaternions
Make/FREE wR = {1, 0, 0, 0}
Make/FREE wI = {0, 1, 0, 0}
Make/FREE wJ = {0, 0, 1, 0}
Make/FREE wK = {0, 0, 0, 1}
MatrixOp/O rW = quat(wR) * quat(wI) // rW is the result wave
Printf "1i = {%g,%g,%g,%g} (i)r", rW[0], rW[1], rW[2], rW[3]
MatrixOp/O rW = quat(wI) * quat(wI)
Printf "ii = {%g,%g,%g,%g} (-1)r", rW[0], rW[1], rW[2], rW[3]
MatrixOp/O rW = quat(wI) * quat(wJ)
Printf "ij = {%g,%g,%g,%g} (k)r", rW[0], rW[1], rW[2], rW[3]
MatrixOp/O rW = quat(wJ) * quat(wI)
Printf "ji = {%g,%g,%g,%g} (-k)r", rW[0], rW[1], rW[2], rW[3]
End
上边的例子中:
- wR, wI, wJ,wK是包含四元数w, x, y, z数值的wave。
- rW是输出结果。
- quat()是MatrixOp的四元符号。
还可以用标量scalar或含有x, y, z的数组创建四元数,比如:
Function QuaternionTokenDemo()
Make/FREE wI = {0, 1, 0, 0} // w, x, y, z
Make/FREE wXYZ = {1, 0, 0} // x, y, z
MatrixOp/O rW = quat(wI) * quat(wXYZ)
Printf "ii = {%g,%g,%g,%g} (-1)r", rW[0], rW[1], rW[2], rW[3]
MatrixOp/O rW = quat(wI) * quat(wXYZ) * quat(3)
Printf "3ii = {%g,%g,%g,%g} (-3)r", rW[0], rW[1], rW[2], rW[3]
End
- quat(wXYZ)是把一个含有x, y, z的wave转换为纯虚四元数(w为0),wXYZ可以是3 *1或者1 *3的wave。
- quat(3)把标量3转换为纯实的四元数,其x, y, z分量为0。
注意:quat()的输入必须是实数。
小结:
希望本文对你有所帮助 ^ _ ^