15 复数
Complex Numbers
本节译者:段园家
本节校审:张梓源(ChatGPT辅助)
Stan supports complex scalars, matrices, and vectors as well as real-based ones.
Stan 在支持实数的标量、矩阵和向量的同时也支持复数的标量、矩阵和向量。
15.1 Working with complex numbers
使用复数
This section describes the complex scalar type, including how to build complex numbers, assign them, and use them in arrays and functions.
本节介绍复数标量类型的使用方法,包括如何构建、赋值,以及在数组和函数中的应用。
Constructing and accessing complex numbers
构造和访问复数
Complex numbers can be constructed using imaginary literals. For example,
可以使用虚数字面量来构造复数。例如:
complex z = -1.1 + 2.3i;
produces the complex number \(-1.1 + 2.3i\). This only works if the real and imaginary components are literal numerals. To construct a complex number out of arbitrary real variables, the to_complex()
function may be used. For example, the following code will work if x
and y
are parameters, transformed data, or local variables in a function or model block.
生成复数 \(-1.1 + 2.3i\)。 这种方式仅在实部和虚部都是字面量时有效。 要从任意实变量中构造一个复数,可以使用 to_complex()
函数。 例如,如 果x
和 y
是函数或模型块中的参数、转换数据或局部变量,则以下代码将起作用。
real x = // ...
real y = // ...
complex z = to_complex(x, y);
The real and imaginary parts of the complex number can be accessed with getters as follows.
可以使用 get_real
和 get_imag
函数分别访问复数的实部和虚部。
real x = get_real(z); // x = -1.1
real y = get_imag(z); // y = 2.3
Complex numbers can be compared using equality (or inequality), but not with greater than or less than operators. For example, after running the code above, the following code snippet will print “hello”.
复数可以使用相等(或不相等)进行比较,但不能使用大于或小于运算符进行比较。 例如,运行上面的代码后,下面的代码片段将打印 “hello”。
complex a = 3.2 + 2i;
complex b = to_complex(3.2, 2);
if (a == b) print("hello");
Complex assignment and promotion
复数的分配和提升
Integer- or real-valued expressions may be assigned to complex numbers, with the corresponding imaginary component set to zero.
整数或实值表达式可以分配给复数,相应的虚部设置为零。
complex z1 = 3; // int promoted to 3 + 0i
complex z2 = 3.2; // real promoted to 3.2 + 0.i
Complex arrays
复数数组
Arrays of complex numbers work as usual and allow the usual curly bracket constructors.
复数数组的用法与实数数组类似,也可使用大括号进行构造。
complex z1; complex z2; complex z3;
// ...
array[3] complex zs = { z1, z2, z3 };
for (z in zs) {
print(z);
}
Complex arrays allow assignment into their elements, with integer or real assigned values being promoted to complex.
复数数组允许对其元素进行赋值,被赋的整数或实数值会自动提升为复数。
Complex functions
复数函数
All of the standard complex functions are available, including natural logarithm log(z)
, natural exponentiation exp(z)
, and powers pow(z1, z2)
, as well as all of the trig and hyperbolic trigonometric functions and their inverse, such as sin(z)
, acos(z)
, tanh(z)
and asinh(z)
.
所有标准复函数都可用,包括自然对数 log(z)
、自然指数 exp(z)
和幂函数 pow(z1,z2)
,以及所有三角函数和双曲三角函数及其逆函数,如 sin(z)
、acos(z)
、tanh(z)
和 asinh(z)
。
Promotion also works for complex-valued function arguments, which may be passed integer or real values, which will be promoted before the function is evaluated. For example, the following user-defined complex function will accept integer, real, or complex arguments.
类型提升同样适用于复数函数的参数传递,可以传入整数或实数值,这些值会在函数执行前自动提升为复数。例如,下面这个用户定义的复数函数可以接受整数、实数或复数参数。
complex times_i(complex z) {
complex i = to_complex(0, 1);
return i * z;
}
For instance, times_i(1)
evaluates to the imaginary base \(i\), as does times_i(1.0)
.
例如,times_i(1)
的计算结果为虚数 \(i\),times_i(1.0)
也是如此。
15.2 Complex random variables
复随机变量
The simplest way to model a distribution over a complex random number \(z = x + yi\) is to consider its real part \(x\) and imaginary part \(y\) to have a bivariate normal distribution. For example, a complex prior can be expressed as follows.
对复随机数 \(z = x + yi\) 上的分布进行建模的最简单方法是将其实部 \(x\) 和虚部 \(y\) 视为具有二元正态分布。 例如,一个复数的先验可以表示如下。
complex z;
vector[2] mu;
2] L_Sigma;
cholesky_cov[// ...
[get_real(z), get_imag(z)]' ~ multi_normal_cholesky(mu, L_Sigma);
For example, if z
is data, this can be used to estimate mu
and the covariance Cholesky factor L_Sigma
. Alternatively, if z
is a parameter, mu
and L_Sigma
may constants defining a prior or further parameters defining a hierarchical model.
例如,如果 z
是数据,则可用于估计 mu
和协方差 Cholesky 因子L_Sigma
。或者,如果 z
是一个参数,则 mu
和 L_Sigma
可以是定义了一个先验的常数或者定义一个分层模型的参数。
15.3 Complex matrices and vectors
复数矩阵和向量
Stan supports complex matrices, vectors, and row vectors. Variables of these types are declared with sizes in the same way as their real-based counterparts.
Stan 支持复数矩阵、向量和行向量。 这些类型的变量大小的定义同实数值的相同。
complex_vector[3] v;
complex_row_vector[2] rv;
complex_matrix[3, 2] m;
We can construct vectors and matrices using brackets in the same way as for real-valued vectors and matrices. For example, given the declaration of rv
above, we could assign it to a constructed row vector.
我们可以使用括号构造向量和矩阵,其方式与实值向量和矩阵相同。 例如,给定上面 rv
的声明,我们可以将其分配给一个构造好的行向量。
2 + 3i, 1.9 - 2.3i]; rv = [
Complex matrices and vectors support all of the standard arithetmic operations including negation, addition, subtraction, and multiplication (division involves a solve, and isn’t a simple arithmetic operation for matrices). They also support transposition.
复矩阵和向量支持所有标准的算术运算,包括逻辑非、加法、减法和乘法(除法涉及方程的求解,而不是矩阵之间简单的算术运算)。 它们还支持转置。
Furthermore, it is possible to convert back and forth between arrays and matrices using the to_array
functions.
此外,可以使用 to_array
函数在数组和矩阵之间来回转换。
15.4 Complex linear regression
复线性回归
Complex valued linear regression with complex predictors and regression coefficients looks just like standard regression. For example, if we take x
to be predictors, y
to be an array of outcomes. For example, consider the following complete Stan program for an intercept and slope.
具有复预测变量和回归系数的复值线性回归看起来就像标准回归一样。例如,如果我们把 x
作为预测因子,y
是结果的数组。例如,考虑以下用于截距和斜率的完整 Stan 程序。
data {
int<lower=0> N;
complex_vector[N] x;
complex_vector[N] y;
}parameters {
complex alpha;
complex beta;
}model {
complex_vector[N] eps = y - (alpha + beta * x);
// ...error distribution...
eps ~ }
The question remains of how to fill in the error distribution and there are several alternatives. We consider only two simple alternatives, and do not consider penalizing the absolute value of the error.
问题仍然是如何给出误差分布。我们有几种选择方案,这里只考虑两种简单方案,不涉及对误差绝对值的惩罚。
Independent real and imaginary error
独立的实部误差和虚部误差
The simplest approach to error in complex regression is to give the real and imaginary parts of eps_n
independent independent normal distributions, as follows.
在复回归中最简单的误差设定是假设 eps_n
的实部和虚部服从独立的正态分布,如下所示。
parameters {
// ...
vector[2] sigma;
}// ...
model {
// ...
0, sigma[1]);
get_real(eps) ~ normal(0, sigma[2]);
get_imag(eps) ~ normal(//...hyperprior...
sigma ~ }
A new error scale vector sigma
is introduced, and it should itself get a prior based on the expected scale of error for the problem.
引入了一个新的误差尺度向量 sigma
,它本身应该根据问题的预期误差尺度给出一个先验。
Dependent complex error
相依的复数误差
The next simplest approach is to treat the real and imaginary parts of the complex number as having a multivariate normal prior. This can be done by adding a parameter for correlation to the above, or just working with a multivariate covariance matrix, as we do here.
下一个最简单的方法是将复数的实部和虚部视为服从多元正态的先验。这可以在上一部分添加一个协方差参数来实现,或者只是使用多元协方差矩阵,如下所示。
parameters {
cholesky_factor_corr[2] L_Omega; // correlation matrix
vector[2] sigma; // real, imag error scales
// ...
}// ...
model {
array[N] vector[2] eps_arr;
for (n in 1:N) {
eps_arr[n] = { to_real(eps[n]), to_imag(eps[n]) };
}0, 0]',
eps_arr ~ multi_normal_cholesky([
diag_pre_multiply(sigma, L_Omega));4); // shrink toward diagonal correlation
L_Omega ~ lkj_cholesky(// ... hyperprior ...
sigma ~ }
Here, the real and imaginary components of the error get a joint distribution with correlation and independent scales. The error gets a multivariate normal distribution with zero mean and a Cholesky factor representation of covariance, consisting of a scale vector sigma
and a Cholesky factor or a correlation matrix, L_Omega
. The prior on the correlations is concentrated loosely around diagonal covariance, and the prior on the scales is left open. In order to vectorize the call to multi_normal_cholesky
, the vector of complex numbers needs to be converted to an array of size 2 vectors.
在这里,误差的实部和虚部是具有相关和独立尺度的联合分布。误差项服从均值为零的多元正态分布,其协方差采用 Cholesky 分解表示,由尺度向量 sigma
和相关矩阵的 Cholesky 因子 L_Omega
构成。相关性的先验松散地分布在对角协方差附近,尺度上的先验未被指定。为了对 multi_normal_cholesky
的调用进行矢量化操作,需要将复数向量转换为大小为2的向量数组。