1\chapter{Complex matrices}
2\label{chap:complex}
3
4\section{Introduction}
5\label{sec:cmplx-intro}
6
7Native support for complex matrices was added to gretl in version
82019d. Not all of hansl's matrix functions accept complex input, but
9we have enabled a sizable subset of these functions which should
10suffice for most econometric purposes.
11
12Complex numbers are not used in most areas of econometrics, but there
13are a few notable exceptions: among these, complex numbers allow for
14an elegant treatment of univariate spectral analysis of time series,
15and become indispensable if you consider multivariate spectral
16analysis---see for example \cite{shumwaystoffer2017}. A more recent
17example is the numerical solution of linear models with rational
18expectations, which are widely used in modern macroeconomics, for
19which the complex Schur factorization has become the tool of choice
20\citep{klein2000}.
21
22A first point to note is that complex values are treated as a special
23case of the hansl \texttt{matrix} type; there's no \texttt{complex}
24type as such. Complex scalars fall under the \texttt{matrix} type as
25$1 \times 1$ matrices; the hansl \texttt{scalar} type is only for real
26values (as is the \texttt{series} type). A $1 \times 1$ complex matrix
27should do any work you might require of a complex scalar.
28
29Before we proceed to the details of complex matrices in gretl, here's
30a brief reminder of the revelant concepts and notation. Complex
31numbers are pairs of the form $a + b\,i$ where $a$ and $b$ are real
32numbers and $i$ is defined as the square root of $-1$: $a$ is the real
33part and $b$ the imaginary part. One can specify a complex number
34either via $a$ and $b$ or in ``polar'' form. The latter pertains to
35the complex plane, which has the real component on the horizontal axis
36and the imaginary component on the vertical. The polar representation
37of a complex number is composed of the length $r$ of the ray from the
38origin to the point in question and the angle $\theta$ subtended
39between the positive real axis and this ray, measured
40counter-clockwise in radians. In polar form the complex number
41$z = a + b\,i$ can be written as
42\[
43  z = |z|\,(\cos \theta + i\,\sin \theta) = |z|\,e^{i\theta}
44\]
45where $|z| = r = \sqrt{a^2 + b^2}$ and $\theta = \tan^{-1}(b/a)$. The
46quantity $|z|$ is known as the modulus of $z$, and $\theta$ as its
47complex ``argument'' (or sometimes ``phase''). The notation $\bar{z}$
48is used for the complex conjugate of $z$: if $z = a + b\,i$, then
49$\bar{z} = a - b\,i$.
50
51
52
53\section{Creating a complex matrix}
54\label{sec:cmplx-create}
55
56The unique explicit constructor for complex matrices is the
57\cmd{complex()} function. This takes two arguments, giving the real
58and imaginary parts respectively, and sticks them together, as in
59\begin{code}
60C = complex(A, B)
61\end{code}
62Four cases are supported, as follows.
63\begin{itemize}
64\item \texttt{A} and \texttt{B} are both $m \times n$ real matrices
65  Then \texttt{C} is an $m \times n$ complex matrix such that
66  $c_{kj} = a_{kj} + b_{kj}\,i$.
67\item \texttt{A} and \texttt{B} are both scalars: \texttt{C} is a
68  $1 \times 1$ complex matrix such that $c = a + b\,i$.
69\item \texttt{A} is an $m \times n$ real matrix and \texttt{B} is a
70  scalar: \texttt{C} is an $m \times n$ matrix such that
71  $c_{kj} = a_{kj} + b\,i$.
72\item \texttt{A} is a scalar and \texttt{B} is an $m \times n$ real
73  matrix: \texttt{C} is an $m \times n$ matrix such that
74  $c_{kj} = a + b_{kj}\,i$.
75\end{itemize}
76
77In addition, complex matrices may naturally arise as the result of
78certain computations.
79
80With both real and complex matrices in circulation, one may wish to
81determine whether a particular matrix is complex. The function
82\cmd{iscomplex()} can tell you. Passed an identifier, it returns 1
83if it names a complex matrix, 0 if it names a real matrix, or
84\texttt{NA} otherwise.
85
86Note, however, that the \cmd{iscomplex()} function only tells you if a
87certain matrix is endowed with an imaginary part, which may be
88zero. The following code snippet should clarify the point:
89\begin{code}
90matrix z = complex(1,0)
91scalar a = iscomplex(z)
92scalar b = z[imag] == 0
93printf "a = %g, b = %g\n", a, b
94\end{code}
95The code above gives
96\begin{code}
97a = 1, b = 1
98\end{code}
99The test \texttt{a} is non-zero (or ``true'') because the matrix
100\texttt{z} is defined as complex, but \texttt{b}, which tests for an
101all-zero imaginary part of \texttt{z}, is also true. In mathematical
102terms, then, \texttt{z} is effectively a real matrix.
103
104\section{Indexation}
105
106Indexation of complex matrices works as with real matrices, on the
107understanding that each element of a complex matrix is a complex
108pair. So for example \texttt{C[i,j]} gets you the complex pair at row
109\texttt{i}, column \texttt{j} of \texttt{C}, in the form of a
110$1 \times 1$ complex matrix.
111
112If you wish to access just the real or imaginary part of a given
113element, or range of elements, you can use the functions \cmd{Re()}
114or \cmd{Im()}, as in
115\begin{code}
116scalar rij = Re(C[i,j])
117\end{code}
118which gets you the real part of $c_{ij}$.
119
120In addition the dummy selectors \cmd{real} and \cmd{imag} can be
121used to assign to just the real or imaginary component of a complex
122matrix. Here are two examples:
123\begin{code}
124# replace the real part of C with random normals
125C[real] = mnormal(rows(C), cols(C))
126
127# set the imaginary part of C to all zeros
128C[imag] = 0
129\end{code}
130The replacement must be either a real matrix of the same dimensions as
131the target, or a scalar.
132
133Further, the \cmd{real} and \cmd{imag} selectors may be combined
134with regular selectors to access specific portions of a complex matrix
135for either reading or writing. Examples:
136\begin{code}
137# retrieve the real part of a submatrix of C
138matrix R = C[1:2,1:2][real]
139
140# set the imaginary part of C[3,3] to y
141C[3,3][imag] = y
142\end{code}
143
144\section{Operators}
145\label{sec:cmplx-ops}
146
147Most of the operators available for working with real matrices are
148also available for complex ones; this includes the ``dot-operators''
149which work element-wise or by ``broadcasting'' vectors. Moreover,
150mixed operands are accepted, as in \texttt{D = C + A} where \texttt{C}
151is complex and \texttt{A} real; the result, \texttt{D}, will be
152complex. In such cases the real operand is treated as a complex matrix
153with an all-zero imaginary part.
154
155The operators \textit{not} defined for complex values are:
156\begin{itemize}
157\item Those that include the inequality tests ``\verb+>+'' or
158  ``\verb+<+'', since complex values as such cannot be compared as
159  greater or lesser (though they can be compared as equal or not
160  equal).
161\item The (real) modulus operator (percent sign), as in \texttt{x \%
162    y} which gives the remainder on division of \texttt{x} by
163  \texttt{y}.
164\end{itemize}
165
166As for real matrices, the transposition operator ``\cmd{'}'' is
167available in both unary form, as in \texttt{B = A'}, and binary form,
168as in \texttt{C = A'B} (transpose-multiply). But note that for complex
169\texttt{A} this means the conjugate transpose, $A^\mathrm{H}$. If you
170need the non-conjugated transpose you can use \cmd{transp()}.
171
172You may wish to note: although none of gretl's explicit regression
173functions (or commands) accept complex input you can calculate
174parameter estimates for a least-squares regression of complex $Y$
175($T \times 1$) on complex $X$ ($T \times k$) via \verb|B = X \ Y|.
176
177\section{Functions}
178\label{sec:cmplx-funcs}
179
180To give an idea of what works, and what doesn't, for complex
181matrices, we'll walk through the hansl function-space using the
182categories employed in gretl's online ``Function reference'' (under the
183\textsf{Help} menu in the GUI program).
184
185\subsection{Linear algebra}
186
187The functions that accept complex arguments are: \cmd{cholesky},
188\cmd{det}, \cmd{ldet}, \cmd{eigensym} (for Hermitian matrices),
189\cmd{ffti}, \cmd{inv}, \cmd{ginv}, \cmd{hdprod}, \cmd{mexp},
190\cmd{mlog}, \cmd{qrdecomp}, \cmd{rank}, \cmd{svd}, \cmd{tr}, and
191\cmd{transp}. Note, however, that \cmd{mexp} and \cmd{mlog} require
192that the input matrix be diagonalizable, and \cmd{cholesky} requires a
193positive definite Hermitian matrix.
194
195In addition the new functions \cmd{eigen} and \cmd{fft2} are
196complex-supporting versions of \cmd{eigengen} and \cmd{fft},
197respectively (see section~\ref{sec:cmplx-compat} for details). And
198there are the complex-only functions \cmd{ctrans}, which gives the
199conjugate transpose,\footnote{The \cmd{transp} function gives the
200  straight (non-conjugated) transpose of a complex matrix.} and
201\cmd{schur} for the Schur factorization.
202
203\subsection{Matrix building}
204
205Given what was said in section~\ref{sec:cmplx-create} above, several
206of the functions in this category should be thought of as applying to
207the real or imaginary part of a complex matrix (for example,
208\cmd{ones} and \cmd{mnormal}), and are of course usable in that
209way.  However, some of these functions can be applied to complex
210matrices as such, namely, \cmd{diag}, \cmd{diagcat},
211\cmd{lower}, \cmd{upper}, \cmd{vec}, \cmd{vech} and
212\cmd{unvech}.
213
214Please note: when \cmd{unvech} is applied to a suitable real
215vector it produces a symmetric matrix, but when applied to a complex
216vector it produces a Hermitian matrix.
217
218The only functions \textit{not} available for complex matrices are
219\cmd{cnameset} and \cmd{rnameset}. That is, you cannot name the
220columns or rows of such matrices (although this restriction could
221probably be lifted without great difficulty).
222
223\subsection{Matrix shaping}
224
225The functions that accept complex input are: \cmd{cols},
226\cmd{rows}, \cmd{mreverse}, \cmd{mshape}, \cmd{selifc},
227\cmd{selifr} and \cmd{trimr}.
228
229The functions \cmd{msortby}, \cmd{sort} and \cmd{dsort} are
230excluded for the reason mentioned in section~\ref{sec:cmplx-ops}.
231
232\subsection{Statistical}
233
234Supported for complex input: \cmd{meanc}, \cmd{meanr},
235\cmd{sumc}, \cmd{sumr}, \cmd{prodc} and \cmd{prodr}. And
236that's all.
237
238\subsection{Mathematical}
239
240In the matrix context, these are functions that are applied element by
241element. For complex input the following are supported: \cmd{log},
242\cmd{exp} and \cmd{sqrt}, plus all of the trigonometric
243functions with the exception of \cmd{atan2}.
244
245In addition there are the complex-only functions \cmd{cmod}
246(complex modulus, also accessible via \cmd{abs}), \cmd{carg}
247(complex argument), \cmd{conj} (complex conjugate), \cmd{Re}
248(real part) and \cmd{Im} (imaginary part). Note that
249$\mbox{carg}(z) = \mbox{atan2}(y,x)$ for $z=x +
250y\,i$. Listing~\ref{cmplx-modes} illustrates usage of \cmd{cmod}
251and \cmd{carg}.
252
253\begin{script}[htbp]
254  \scriptcaption{Variant representations of complex numbers. We picked 8
255    points on the unit circle in the complex plane, so their modulus
256    is constant and equal to 1. The \texttt{Polar} matrix below shows
257    that the complex argument is expressed in radians; multiplying by
258    180/$\pi$ gives degrees. The \texttt{chk} matrix verifies that
259    we can retrieve the orginal representation of the complex values
260    from the polar form in either of the two ways mentioned at the
261    start of the chapter: $z = |z|\,(\cos \theta + i\,\sin \theta)$ or
262    $z = |z|\,e^{i\theta}$.}
263  \label{cmplx-modes}
264\begin{scodebit}
265# complex values in a + b*i form
266scalar rp5 = sqrt(0.5)
267matrix A = {1, rp5, 0, -rp5, -1, -rp5,  0,  rp5}'
268matrix B = {0, rp5, 1,  rp5,  0, -rp5, -1, -rp5}'
269matrix Z = complex(A, B)
270
271# calculate modulus and argument
272matrix zmod = cmod(Z)
273matrix theta = carg(Z)
274matrix Polar = zmod ~ theta ~ (theta * 180/$pi)
275cnameset(Polar, "modulus radians degrees")
276printf "%12.4f\n", Polar
277
278# reconstitute the original Z matrix in two ways
279matrix Z1 = zmod .* complex(cos(theta), sin(theta))
280matrix Z2 = zmod .* exp(complex(0, theta))
281matrix chk = Z ~ Z1 ~ Z2
282print chk
283\end{scodebit}
284
285
286  Printing of \texttt{Polar} and \texttt{chk}
287\begin{outbit}
288     modulus     radians     degrees
289      1.0000      0.0000      0.0000
290      1.0000      0.7854     45.0000
291      1.0000      1.5708     90.0000
292      1.0000      2.3562    135.0000
293      1.0000      3.1416    180.0000
294      1.0000     -2.3562   -135.0000
295      1.0000     -1.5708    -90.0000
296      1.0000     -0.7854    -45.0000
297
298 1.00000 + 0.00000i   1.00000 + 0.00000i   1.00000 + 0.00000i
299 0.70711 + 0.70711i   0.70711 + 0.70711i   0.70711 + 0.70711i
300 0.00000 + 1.00000i   0.00000 + 1.00000i   0.00000 + 1.00000i
301-0.70711 + 0.70711i  -0.70711 + 0.70711i  -0.70711 + 0.70711i
302-1.00000 + 0.00000i  -1.00000 + 0.00000i  -1.00000 + 0.00000i
303-0.70711 - 0.70711i  -0.70711 - 0.70711i  -0.70711 - 0.70711i
304 0.00000 - 1.00000i   0.00000 - 1.00000i   0.00000 - 1.00000i
305 0.70711 - 0.70711i   0.70711 - 0.70711i   0.70711 - 0.70711i
306\end{outbit}
307\end{script}
308
309\subsection{Transformations}
310
311In this category only two functions can be applied to complex
312matrices, namely \cmd{cum} and \cmd{diff}.
313
314\section{File input/output}
315
316Complex matrices should be stored and retrieved correctly in the
317XML serialization used for gretl session files (\texttt{*.gretl}).
318
319The functions \cmd{mwrite} and \cmd{mread} work in two modes:
320binary mode if the filename ends with ``\texttt{.bin}'' and text mode
321otherwise. Both modes handle complex matrices correctly if both the
322writing and the reading are to be done by gretl, but for exchange of
323data with ``foreign'' programs text mode will \textit{not} work for
324complex matrices as a whole. The options are:
325\begin{itemize}
326\item In text mode, use \cmd{mwrite} and \cmd{mread} on the two
327  parts of a complex matrix separately, and reassemble the matrix in
328  the target program.
329\item Use binary mode (on the whole matrix), if this is supported for
330  the given foreign program.
331\end{itemize}
332
333At present binary mode transfer of complex matrices is supported for
334\textsf{octave}, \textsf{python} and \textsf{julia}.
335Listing~\ref{cmplx-io} shows some examples: we export a complex matrix
336to each of these programs in turn; calculate its inverse in the
337foreign program; then verify that the result as imported back into
338gretl is the same as that calculated in gretl.
339
340\begin{script}[htbp]
341  \scriptcaption{Exporting and importing complex matrices}
342  \label{cmplx-io}
343\begin{scode}
344set seed 34756
345matrix C = complex(mnormal(3,3), mnormal(3,3))
346D = inv(C)
347
348mwrite(C, "C.bin", 1)
349
350foreign language=octave
351  C = gretl_loadmat('C.bin');
352  gretl_export(inv(C), 'oct_D.bin');
353end foreign
354
355oct_D = mread("oct_D.bin", 1)
356eval D - oct_D
357
358foreign language=python
359   import numpy as np
360   C = gretl_loadmat('C.bin')
361   gretl_export(np.linalg.inv(C), 'py_D.bin')
362end foreign
363
364py_D = mread("py_D.bin", 1)
365eval D - py_D
366
367foreign language=julia
368  C = gretl_loadmat("C.bin")
369  gretl_export(inv(C), "jl_D.bin")
370end foreign
371
372jl_D = mread("jl_D.bin", 1)
373eval D - jl_D
374\end{scode}
375\end{script}
376
377\section{Backward compatibility}
378\label{sec:cmplx-compat}
379
380Compatibility issues arise in two contexts, both related to the fact
381that gretl offered some degree of support for complex matrices before
382they became full citizens of the hansl polity.
383
384\begin{enumerate}
385\item The functions \cmd{fft} (fast Fourier transform for real
386  input) and \cmd{eigengen} (eigenvalues and/or eigenvectors of a
387  non-symmetric real matrix) returned complex matrices in what we may
388  call the ``legacy'' representation. In the case of \cmd{fft} and
389  the eigenvalues from \cmd{eigengen} this took the form of a
390  regular gretl matrix with real values in the first (or odd-numbered)
391  column(s) and imaginary parts in the second (or even-numbered)
392  column(s). Since calculating with such matrices using the standard
393  matrix operators would result in nonsense, we provided the tailored
394  functions \cmd{cmult} and \cmd{cdiv}.
395
396  In the case of complex eigenvectors from \cmd{eigengen}---well,
397  you probably don't want to know, but if you do, consult the help text
398  for \cmd{eigengen}; they were not easy for a user to handle!
399\item The function packages \texttt{cmatrix} and
400  \texttt{ghosts}. These were developed to support frequency-domain
401  analysis via gretl in the absence of built-in complex matrix
402  functionality. The \texttt{cmatrix} package was needed as an
403  dependency for \texttt{ghosts} (multivariate spectral analysis).
404\end{enumerate}
405
406So what happens with these functions and function packages under the
407new regime? The resolution on the two built-in functions is this:
408\begin{itemize}
409\item \cmd{fft} and \cmd{eigengen} continue to behave exactly as
410  before. They do not accept complex input and they produce old-style
411  output. In the documentation they are marked as legacy functions,
412  not for use in newly written hansl code.
413\item We have added new counterpart functions, \cmd{fft2} and
414  \cmd{eigen}. These accept either real or complex input and they
415  produce new-style complex output in both cases.
416\end{itemize}
417
418On the affected packages: \texttt{cmatrix} is no longer required, and
419is not be supported any more. But an updated version of
420\texttt{ghosts}, which uses gretl's native complex functionality, is
421available.
422
423We might mention that the \cmd{ffti} function (inverse Fourier
424transform) is backward compatible: the new functionality is just a
425superset of the old. The input must be complex, and is accepted by
426\cmd{ffti} in either the legacy or the new format. The output is
427real if the input is Hermitian, which in this case means that the
428first (zero-frequency) row is real and the remaining rows are
429conjugate symmetrical about their mid-point. That's the only case that
430can arise when \cmd{ffti} is used on output from the old
431\cmd{fft} (which only accepted real input).  Otherwise
432(non-Hermitian complex input, which can arise only under the new
433scheme) the output will be complex, and in the new format.
434
435%%% Local Variables:
436%%% mode: latex
437%%% TeX-master: "gretl-guide"
438%%% End:
439