文章目录

  • 1. 常用符号
    • 1.1 SX 符号
    • 1.2 DM 符号
    • 1.3 MX 符号
    • 1.4 SX 和 MX 的混合
    • 1.5 稀疏类
      • 1.5.1 获取和设置矩阵中的元素
    • 1.6 算术运算
      • 1.6.1 乘法
      • 1.6.2 transpose
      • 1.6.3 reshape()
      • 1.6.4 vertcat()/horzcat()
      • 1.6.5 split
      • 1.6.6 Inner product
    • 1.7 查询属性
    • 1.8 线性代数
    • 1.9 微积分 - 算法微分
      • 1.9.1 句法

1. 常用符号

1.1 SX 符号

  SX 数据类型用于表示矩阵,其元素由一系列一元和二元运算序列组成的符号表达式组成。要查看它在实践中的工作原理,请启动交互式 Python shell(例如,通过从 Linux 终端或在集成开发环境(如 Spyder)中键入 ipython)或启动 MATLAB 或 Octave 的图形用户界面。 假设 CasADi 已正确安装,您可以将该库导入工作区,如下所示:

from casadi import *

使用以下语法创建一个变量 x:

x = MX.sym("x")
print(x)

运行后输出结果为:

x

上述代码创建一个 1×1 矩阵,即一个名字叫 x 的符号基元(是个标量)。 这只是显示名称,而不是标识符。 多个变量可以具有相同的名称,但仍然不同。 标识符是返回值。 此外,还可以调用函数 SX.sym (带参数)来创建向量或矩阵值符号变量:

y = SX.sym('y',5)
Z = SX.sym('Z',4,2)
print(y)
print(z)

运行后输出结果为:

[y_0, y_1, y_2, y_3, y_4]
[[Z_0, Z_4],
 [Z_1, Z_5],
 [Z_2, Z_6],
 [Z_3, Z_7]]

上述代码分别创建一个5×1矩阵(即向量)和一个具有符号基元的4×2矩阵。 SX.sym 是一个(静态)函数,它返回一个 SX 实例。 声明变量后,现在可以以直观的方式形成表达式:

f = x**2 + 10
f = sqrt(f)
print(f)

运行后输出结果为:

sqrt((10+sq(x)))

除此之外,还可以创建没有常量 SX 实例:

B1 = SX.zeros(4,5): # 一个全零的密集 4×5 空矩阵
B2 = SX(4,5): # 全零的稀疏 4×5 空矩阵
B4 = SX.eye(4): # 稀疏的4×4矩阵,对角线为1
print(B1)
print(B2)
print(B4)

运行后输出结果为:

B1: @1=0,
[[@1, @1, @1, @1, @1],
 [@1, @1, @1, @1, @1],
 [@1, @1, @1, @1, @1],
 [@1, @1, @1, @1, @1]]
B2:
[[00, 00, 00, 00, 00],
 [00, 00, 00, 00, 00],
 [00, 00, 00, 00, 00],
 [00, 00, 00, 00, 00]]
B4: @1=1,
[[@1, 00, 00, 00],
 [00, @1, 00, 00],
 [00, 00, @1, 00],
 [00, 00, 00, @1]]

  注意:注意上述表达之间的区别:当打印带有结构零(稀疏矩阵中未显式赋值的元素)的表达式时,这些零将表示为 00,以将它们与实际零 @1 (实际显式赋值的元素,print后使用@1来表示0,以便区分结构零与实际零之间的区别)区分开来。

除了上述的使用方法外,下表罗列了常用的 SX 表达式:

函数表达式 用途
SX.sym(name,n,m) 创建一个 n×m 符号基元
SX.zeros(n,m) 创建一个所有元素全为零的n×m密集矩阵
SX(n,m) 创建一个所有元素为零的 n×m 稀疏矩阵
SX.ones(n,m) 创建一个包含所有 1 的 n×m 密集矩阵
SX.eye(n) 创建一个 n×n 对角矩阵,对角线元素为1,其他地方元素为结构零
SX(scalar_type) 使用参数给定的值创建一个标量(1×1 矩阵),可以显式使用此方法,例如 SX(9),或隐式,例如9 * SX.ones(2,2)
SX(matrix_type) 创建一个给定数值矩阵的矩阵,该数值矩阵为NumPy或SciPy矩阵(在Python中)或为稠密或稀疏矩阵(在MATLAB / Octave中)。在 MATLAB/Octave 中,例如SX([1,2,3,4]) 表示行向量,SX([1;2;3;4]) 表示列向量,SX([1,2;3,4]) 表示 2×2 矩阵,该方法可以显式或隐式使用。
repmat(v,n,m) 将表达式v垂直方向重复表n次,水平方向重复m次。例如:repmat(SX(3),2,1) 创建一个所有元素为 3 的 2×1 矩阵。
SX(list) (仅限 Python) 使用列表中的元素创建列向量(n×1 矩阵),例如SX([1,2,3,4])。(注意 Python 列表和 MATLAB/Octave 水平串联的区别,两者都使用方括号语法)
SX(list of list)(仅限 Python) 使用列表中的元素创建一个密集矩阵,例如SX([[1,2],[3,4]]) 或使用 SX([[1,2,3,4]]) 创建一个(1×n 矩阵)行向量。

1.2 DM 符号

  DM 与 SX 非常相似,但不同的是非零元素是数值而不是符号表达式。 DM 语法与 SX 也相同,除了部分类似于 SX.sym 等函数。

  DM 主要用于在 CasADi 中存储矩阵以及作为函数的输入和输出。 它不打算用于计算密集型计算。 为此,请使用 MATLAB 中的内置密集或稀疏数据类型、Python 中的 NumPy 或 SciPy 矩阵或基于表达式模板的库,例如 C++ 中的 eigen、ublas 或 MTL。 类型之间的转换通常很简单:

C = DM(2,3)C_dense = C.full()
from numpy import array
C_dense = array(C) # equivalentC_sparse = C.sparse()
from scipy.sparse import csc_matrix
C_sparse = csc_matrix(C) # equivalent

  SX 的更多使用示例可以在 http://install.casadi.org/ 的示例包中找到。 有关此类(和其他类)特定功能的文档,例如 C++ API, 可以在http://docs.casadi.org/上找到。


1.3 MX 符号

  下面代码的输出是一个 2×2 矩阵,注意看这里的第一句话@1=3,也就意味着第二行的输出中@1代表3,输出结果意味着CasADi为矩阵f的每个条目创建了新的表达式(SX 类型)。

x = SX.sym('x',2,2)
y = SX.sym('y')
f = 3*x + y
print(f)
print(f.shape)

运行后输出结果为:

@1=3,
[[((@1x_0)+y), ((@1x_2)+y)],
 [((@1x_1)+y), ((@1x_3)+y)]]
(2, 2)

  除了上面的方式外,我们还可以使用第二种更通用的矩阵表达式类型MX。 MX 类型允许像 SX 一样构建由一系列基本操作组成的表达式。 但与 SX 不同的是,这些基本运算不限于标量一元或二元运算(R→R\mathbb{R}→\mathbb{R}R→R 或 R×R→R\mathbb{R}×\mathbb{R}→\mathbb{R}R×R→R)。 取而代之的是,用于形成MX表达式的基本运算可以为通用的多个稀疏矩阵值输入,多个稀疏矩阵值输出函数: Rn1×m1×…×RnN×mN→Rp1×q1×…×RpM×qM\mathbb{R}^{{n_1}×{m_1}}×…×\mathbb{R}^{{n_N}×{m_N}}→\mathbb{R}^{{p_1}×{q_1}}×…×\mathbb{R}^{{p_M}×{q_M}}Rn1​×m1​×…×RnN​×mN​→Rp1​×q1​×…×RpM​×qM​,例如:

x = MX.sym('x',2,2)
y = MX.sym('y')
f = 3*x + y
print(f)
print(f.shape)

运行后输出结果为:

((3*x)+y)
(2, 2)

  上述两段代码结果相同, MX 符号仅由两个运算(一个乘法和一个加法)组成,而 SX 等价物有八个(每个元素由两个构成,f(1,1)由(@1x_0)和y构成)。 因此,当使用具有许多元素的自然向量或矩阵值的操作时,MX 可以更经济。

  MX支持使用与SX相同的语法来获取和设置元素,但是实现方式却大不相同。 例如,测试打印 2×2 符号变量左上角的元素:

x = MX.sym('x',2,2)
print(x[0,0])

输出应理解为等于 x 的第一个(即 C++ 中的索引 0)结构上非零元素的表达式,与上面 SX 情况下的 x_0 不同,它是第一个(索引 0) 矩阵的位置。

  设置元素时用法相似:

x = MX.sym('x',2)
A = MX(2,2)
A[0,0] = x[0]
A[1,1] = x[0]+x[1]
print('A:', A)

运行后输出结果为:

A: (project((zeros(2x2,1nz)[0] = x[0]))[1] = (x[0]+x[1]))

这个输出结果可以理解为:从一个全零稀疏矩阵开始,一个元素被分配给 x_0。 然后将其投影到不同稀疏度的矩阵,并将另一个元素分配给 x_0+x_1。


1.4 SX 和 MX 的混合

  不能将SX对象与MX对象相乘,也不能执行任何其他操作以将两者混合在同一表达式图中。 但是却可以在 MX 图中包括对由 SX 表达式定义的函数的调用。如果需要提升程序的效率,可以混合使用 SX 和 MX,因为由 SX 表达式定义的函数每个操作的开销要低得多,这使得系统完成一系列标量操作的速度更快。 因此,SX 表达式旨在用于低级操作,而 MX 表达式则用于实现负责的操作,例如实现 NLP 的约束函数。


1.5 稀疏类

  CasADi 中的矩阵使用压缩列存储 (CCS) 格式进行存储。 这是稀疏矩阵的标准格式,允许有效执行线性代数运算,例如逐元素运算、矩阵乘法和转置。 在 CCS 格式中,稀疏模式使用维度(行数和列数)和两个向量进行解码。 第一个向量包含每列的第一个结构上非零元素的索引,第二个向量包含每个非零元素的行索引。 有关 CCS 格式的更多详细信息,请参见例如 Netlib 上线性系统解决方案的模板。 请注意,CasADi 对稀疏矩阵和密集矩阵使用 CCS 格式。

  CasADi 中的稀疏模式存储为 Sparsity 类的实例,该类是引用计数的,这意味着多个矩阵可以共享相同的稀疏模式,包括 MX 表达式图以及 SX 和 DM 的实例。 稀疏类也被缓存,这意味着总是避免创建相同稀疏模式的多个实例。

  以下列表总结了构建新稀疏模式的最常用方法:

函数名 功能
Sparsity.dense(n,m) 创建一个密集的 n×m 稀疏模式
Sparsity(n,m) 创建一个稀疏的 n×m 稀疏模式
Sparsity.diag(n) 创建对角线 n×n 稀疏模式
Sparsity.upper(n) 创建一个上三角 n×n 稀疏模式
Sparsity.lower(n) 创建一个下三角 n×n 稀疏模式

  稀疏类可用于创建非标准矩阵,例如:

print(SX.sym('x',Sparsity.lower(3)))

运行后输出结果为:

[[x_0, 00, 00],
 [x_1, x_3, 00],
 [x_2, x_4, x_5]]

1.5.1 获取和设置矩阵中的元素

  要获取或设置 CasADi 矩阵类型(SX、MX 和 DM)中的一个元素或一组元素,我们在 Python 中使用方括号,在 C++ 和 MATLAB 中使用圆括号。 按照这些语言的惯例,索引在 C++ 和 Python 中从 0 开始,而在 MATLAB 中从 1 开始。 在 Python 和 C++ 中,我们允许负索引指定从末尾开始计数的索引。 在 MATLAB 中,使用 end 关键字从末尾开始索引。

  索引可以用一个索引或两个索引来完成。 使用两个索引,可以访问特定行(或一组或多行)和特定列(或一组列)。 使用一个索引,可以访问一个元素(或一组元素),从左上角开始,按列到右下角。 无论在结构上是否为零,所有元素都被计算在内。 例如:

M = SX([[3,7],[4,5]])
print(M[0,:])
M[0,:] = 1
print(M)

运行后输出结果为:

[[3, 7]]
@1=1,
[[@1, @1],
 [4, 5]]

  与 Python 的 NumPy 不同,CasADi 片段不是左侧数据的视图; 相反,片段访问(Slice access)复制数据。 因此,在以下示例中,矩阵 m 根本没有改变:

M = SX([[3,7],[4,5]])
M[0,:][0,0] = 1
print(M)

运行后输出结果为:

[[3, 7],
 [4, 5]]

  下面详细说明获取和设置矩阵元素。 该讨论适用于 CasADi 的所有矩阵类型。

  通过提供行列对或其展平索引(从矩阵的左上角开始逐列)来获取或设置单元素访问:

M = diag(SX([3,4,5,6]))
print(M)

运行后输出结果为:

[[3, 00, 00, 00],
 [00, 4, 00, 00],
 [00, 00, 5, 00],

[00, 00, 00, 6]]

print(M[0,0])
print(M[1,0])
print(M[-1,-1])

运行后输出结果为:

3
00
6

  片段访问(Slice access)意味着一次设置多个元素。 这比一次设置一个元素要高效得多。 可以通过提供 (start , stop , step) 元组来获取或设置片段。 在 Python 和 MATLAB 中,CasADi 使用标准语法:

print(M[:,1])
print(M[1:,1:4:2])  # 对应(start , stop , step)

运行后输出结果为:

[00, 4, 00, 00]

[[4, 00],
 [00, 00],
 [00, 6]]

  列表访问类似于(但效率可能低于)片段访问:

M = SX([[3,7,8,9],[4,5,6,1]])
print(M)
print(M[0,[0,3]], M[[5,-6]])

运行后输出结果为:

[[3, 7, 8, 9],
 [4, 5, 6, 1]]
[[3, 9]] [6, 7]


1.6 算术运算

1.6.1 乘法

  CasADi 支持大多数标准算术运算,例如加法、乘法、幂、三角函数等:

x = SX.sym('x')
y = SX.sym('y',2,2)
print(sin(y)-x)

运行后输出结果为:

[[(sin(y_0)-x), (sin(y_2)-x)],
 [(sin(y_1)-x), (sin(y_3)-x)]]

  在 C++ 和 Python(但不是在 MATLAB 中)中,标准乘法运算(使用 *)仍用于元素乘法(在 MATLAB .* 中)。 对于矩阵乘法,使用 A @ B 或 (mtimes(A,B) in Python 3.4+):

print(y*y, y@y)

运行后输出结果为:

[[sq(y_0), sq(y_2)],
 [sq(y_1), sq(y_3)]]
[[(sq(y_0)+(y_2*y_1)), ((y_0*y_2)+(y_2*y_3))],
 [((y_1*y_0)+(y_3*y_1)), ((y_1*y_2)+sq(y_3))]]

按照 MATLAB 中的惯例,当任一参数为标量时,使用 * 和 .* 的乘法是等效的。

1.6.2 transpose

  转置使用 Python 中的语法 A.T、C++ 中的 A.T() 以及 A 或 A 形成。 在 MATLAB 中:

print(y)
print(y.T)

运行后输出结果为:

[[y_0, y_2],
 [y_1, y_3]]

[[y_0, y_1],
 [y_2, y_3]]

1.6.3 reshape()

  重塑(reshape)意味着改变行数和列数,但保留元素数和非零元素的相对位置。 这是一个计算成本非常低的操作,它使用以下语法执行:

x = SX.eye(4)
print(reshape(x,2,8))

运行后输出结果为:

@1=1,
[[@1, 00, 00, 00, 00, @1, 00, 00],
 [00, 00, @1, 00, 00, 00, 00, @1]]

1.6.4 vertcat()/horzcat()

  串联意味着水平或垂直堆叠矩阵。 由于在 CasADi 中存储元素的列主要方式,水平堆叠矩阵是最有效的。 实际上是列向量的矩阵(即由单列组成)也可以有效地垂直堆叠。 使用 Python 和 C++ 中的函数 vertcat 和 horzcat(采用可变数量的输入参数)并在 MATLAB 中使用方括号执行垂直和水平连接:

x = SX.sym('x',5)
y = SX.sym('y',5)
print(vertcat(x,y))

运行后输出结果为:

[x_0, x_1, x_2, x_3, x_4, y_0, y_1, y_2, y_3, y_4]

print(horzcat(x,y))

运行后输出结果为:

[[x_0, y_0],
 [x_1, y_1],
 [x_2, y_2],
 [x_3, y_3],
 [x_4, y_4]]

  这些函数还有一些变体,它们将列表(在 Python 中)或元胞数组(在 Matlab 中)作为输入:

L = [x,y]
print(hcat(L))

运行后输出结果为:

[[x_0, y_0],
 [x_1, y_1],
 [x_2, y_2],
 [x_3, y_3],
 [x_4, y_4]]

1.6.5 split

  水平和垂直拆分是上面介绍的水平和垂直串联的逆操作。 要将表达式水平拆分为 n 个较小的表达式,除了要拆分的表达式之外,还需要提供长度为 n+1 的向量偏移。 偏移向量的第一个元素必须是 0,最后一个元素必须是列数。 其余元素必须按非递减顺序排列。然后,拆分操作的输出 i 包含具有 offset[i]≤c<offset[i+1]offset[i]≤c<offset[i+1]offset[i]≤c<offset[i+1] 的列 c。下面演示了语法:

x = SX.sym('x',5,2)
w = horzsplit(x,[0,1,2])
print(w[0], w[1])

运行后输出结果为:

[x_0, x_1, x_2, x_3, x_4] [x_5, x_6, x_7, x_8, x_9]

  vertsplit 操作的工作原理类似,但偏移向量指的是行:

w = vertsplit(x,[0,3,5])
print(w[0], w[1])

运行后输出结果为:

[[x_0, x_5],
 [x_1, x_6],
 [x_2, x_7]]
[[x_3, x_8],
 [x_4, x_9]]

  对于上述垂直拆分,可以使用片段访问来代替水平和垂直拆分:

w = [x[0:3,:], x[3:5,:]]
print(w[0], w[1])

运行后输出结果为:

[[x_0, x_5],
 [x_1, x_6],
 [x_2, x_7]]
[[x_3, x_8],
 [x_4, x_9]]

  对于 SX 创建的变量,这种替代方法是完全等效的,但对于 MX 图,当需要所有拆分表达式时,使用 horzsplit/vertsplit 的效率要高得多。

1.6.6 Inner product

  内积,定义为 <A,B>:=tr(AB)=∑i,jAi,jBi,j<A,B>:=tr(AB)=∑_{i,j}A_{i,j}B_{i,j}<A,B>:=tr(AB)=∑i,j​Ai,j​Bi,j​,创建如下:

x = SX.sym('x',2,2)
print(dot(x,x))

运行后输出结果为:

(((sq(x_0)+sq(x_1))+sq(x_2))+sq(x_3))

  许多上述操作也是为稀疏类定义的,经过 vertcat、horzsplit、转置、加法(返回两个稀疏模式的并集)和乘法(返回两个稀疏模式的交集)等操作后返回的矩阵也是稀疏的。

1.7 查询属性

  可以通过调用适当的成员函数来检查矩阵或稀疏模式是否具有特定属性。 例如查询矩阵大小:

y = SX.sym('y',10,1)
print(y.shape)

运行后输出结果为:

(10, 1)

  查询某个矩阵 A 的属性常用的操作有下面这些:

函数名 功能
A.size1() 行数
A.size2() 列数
A.shape (在 MATLAB 中的“size”)形状,即对 (nrow,ncol)
A.numel() 元素个数,即 nrow∗ncol
A.nnz() 结构上非零元素的数量,如果密集,则等于 A.numel()。
A.sparsity() 检索对稀疏模式的引用
A.is_dense() 是一个密集矩阵,即没有结构零
A.is_scalar() 矩阵是否为标量,即维度为 1×1?
A.is_column() 矩阵是一个向量,即维度为 n 比 1?
A.is_square() 矩阵是方阵吗?
A.is_triu() 是矩阵上三角吗?
A.is_constant() 矩阵项都是常数吗?
A.is_integer() 矩阵项都是整数值吗?

1.8 线性代数

  CasADi 支持有限数量的线性代数运算,例如 对于线性方程组的解:

A = MX.sym('A',3,3)
b = MX.sym('b',3)
print(solve(A,b))

运行后输出结果为:

(A\b)

1.9 微积分 - 算法微分

  CasADi 最核心的功能是algorithmic(or automatic)微分 (AD)。 对于函数 f:RN→RMf:\mathbb{R}^N→\mathbb{R}^Mf:RN→RM:
y=f(x),y=f(x),y=f(x),
前向模式方向导数(forward mode directional derivatives)可用于计算 Jacobian-times-vector 乘积:

y^=∂f∂xx^\hat{y} = \frac{\partial f}{\partial x} \hat{x}y^​=∂x∂f​x^
类似地,反向模式方向导数(reverse mode directional derivatives)可用于计算雅可比转置时间向量乘积:
x^=(∂f∂x)Ty^\hat{x} = (\frac{\partial f}{\partial x})^T \hat{y}x^=(∂x∂f​)Ty^​

  正向和反向模式方向导数的计算成本与评估 f(x) 成正比,而与 x 的维数无关。

  CasADi 还能够有效地生成完整的、稀疏的雅可比行列式。 其算法非常复杂,但基本上包括以下步骤:

  • 自动检测 Jacobian 的稀疏模式
  • 使用图着色技术找到构建完整雅可比行列式所需的一些前向和/或方向导数
  • 以数字或符号方式计算方向导数
  • 计算雅可比行列式

Hessian 的计算方法是首先计算梯度,然后执行与上述相同的步骤,以与上述相同的方式计算梯度的雅可比矩阵,同时利用对称性。

1.9.1 句法

  计算雅可比行列式的表达式:

A = SX.sym('A',3,2)
x = SX.sym('x',2)
print(jacobian(A@x,x))

运行后输出结果为:

[[A_0, A_3],
 [A_1, A_4],
 [A_2, A_5]]

  当微分表达式为标量时,还可以计算矩阵意义上的梯度:

print(gradient(dot(A,A),A))

运行后输出结果为:

[[(A_0+A_0), (A_3+A_3)],
 [(A_1+A_1), (A_4+A_4)],
 [(A_2+A_2), (A_5+A_5)]]

请注意,与 jacobian 不同,梯度始终返回一个密集向量。

Hessians 和作为副产品的梯度计算方法如下:

[H,g] = hessian(dot(x,x),x)
print('H:', H)

运行后输出结果为:

H: @1=2,
[[@1, 00],
 [00, @1]]

  对于计算雅可比乘法向量乘积,jtimes 函数——执行前向模式 AD——通常比创建完整雅可比矩阵和执行矩阵向量乘法更有效:

A = DM([[1,3],[4,7],[2,8]])
x = SX.sym('x',2)
v = SX.sym('v',2)
f = mtimes(A,x)
print(jtimes(f,x,v))

运行后输出结果为:

[(v_0+(3v_1)), ((4v_0)+(7v_1)), ((2v_0)+(8*v_1))]

jtimes 函数可选地计算转置雅可比次向量乘积,即反向模式 AD:

w = SX.sym('w',3)
f = mtimes(A,x)
print(jtimes(f,x,w,True))

运行后输出结果为:

[(((2w_2)+(4w_1))+w_0), (((8w_2)+(7w_1))+(3*w_0))]

CasADi——数据类型详解与基本操作介绍相关推荐

  1. python六大数据类型详解

    python 六大数据类型详解 文章目录 python 六大数据类型详解 数据类型简介 Number(数值) String(字符串) Python字符串的45个方法详解 一.大小写转换 01.capi ...

  2. 为什么要设定PHP数据类型,php数据类型详解

    php数据类型详解 PHP 支持8种基本的数据类型. 四种标量类型: boolean (布尔型)integer (整型)float (浮点型, 也称作 double)string (字符串) 两种复合 ...

  3. Redis数据类型详解(五种)

    Redis支持五种数据类型,即string(字符串).hash(哈希).list(列表).set(集合)及zset(sorted set:有序集合),云吞铺子分享Redis数据类型谅解: Redis数 ...

  4. mysql8.0日期类型_mysql8.0.19基础数据类型详解

    mysql基础数据类型 mysql常用数据类型概览 ![1036857-20170801181433755-146301178](D:\笔记\mysql\复习\1036857-201708011814 ...

  5. Java八大基本数据类型-详解

    Java八大基本数据类型-详解 3.5 八大基本数据类型 Java中的八大基本数据类型在我们学习Java编程中非常重要,可以说是Java编程的起步.这节会为大家非常细致地介绍如何使用这八大基本数据类型 ...

  6. Python数据类型详解03

    原文博客地址: Python数据类型详解03 第一篇Python数据类型详解01中主要介绍了Python中的一些常用的数据类型的基础知识 第二篇Python数据类型详解02文章中, 详细介绍了数字(N ...

  7. JavaScript 数据类型详解(对象、set、map)

    在上一篇博客中我已经详细介绍了JavaScript 中的字符串和数组,没看过的戳[JavaScript 数据类型详解(字符串.数组)]哦,现在我们来看看对象(Object)和 ES6 新增的 Set ...

  8. MySQL数据库,从入门到精通:第十二篇——MySQL数据类型详解

    MySQL数据库,从入门到精通:第十二篇--MySQL数据类型详解 第 12 章_MySQL数据类型精讲 1. MySQL中的数据类型 2. 整数类型 2. 1 类型介绍 2. 2 可选属性 2. 2 ...

  9. python 子字符串 位置_python查找子字符串位置Python变量和数据类型详解

    Python变量和数据类型 Python中数据类型 Python之print语句 Python的注释 Python中什么是变量 Python中定义字符串 Python中raw字符串与多行字符串 Pyt ...

  10. OpenCV 4.x API 详解与C++实例-Mat数据类型详解

    第二节 Mat数据类型详解 1.Mat数据类型描述 我们有多种从现实世界中获取数字图像的方法:数码相机,扫描仪,计算机断层扫描和磁共振成像等等. 在每种情况下,我们(人类)看到的都是图像. 但是,当将 ...

最新文章

  1. mysql数据库名称sid_数据库sid 和数据库名
  2. (12)调用门阶段测试
  3. php-fpm backlog 项的调整
  4. 第四届泰迪杯数据挖掘大赛
  5. feign调用接口参数可以为null吗_FeignClient调用POST请求时查询参数被丢失的情况分析与处理...
  6. bzoj 4401: 块的计数
  7. 菜鸟学python-基础(2)
  8. 文本数据标注工具doccano【介绍最详细的一遍文章】
  9. python排序算法——快速排序时间复杂度O(nlogn)
  10. python谐音梗_谐音梗生成器
  11. 如何运行python 复制粘贴_Python执行选择性粘贴
  12. 传奇手游服务器搭建_传奇手游架设服务器教程
  13. C++ OpenCV相机标定---实心圆点、棋盘格
  14. windows服务器无法安装net3.5 提示:无法通过windows功能控制面板自动安装或卸载windows server角色和功能服务器
  15. 阿里云验证码与通知短信
  16. 大数据就业:学完大数据怎样就业
  17. 关于C和C++的争论
  18. 7-36 大炮打蚊子(15 分)
  19. uniapp手机端图片缓存方案
  20. 国家常用代号 for Mysql数据库

热门文章

  1. 浅谈标签概念及应用场景
  2. bittorrent协议
  3. Metasploit为什么选择Ruby语言(部分)
  4. php eclipse aptana,eclipse 下如何安装 Aptana插件
  5. 修改linux开机启动界面,修改树莓派的开机启动画面,
  6. 大数据和人工智能属于什么专业 - 学大数据和人工智能出来做什么
  7. 来上海度过的第一个五一,我去了哪些地方?
  8. 基于java学生信息管理系统
  9. css滤镜、混合模式、hls颜色值
  10. 《科尼龙作曲家》——简单易用又功能丰富的五线谱编辑和作曲软件