32
$\begingroup$

Given a vector $[x_1,x_2,x_3, \dots, x_n]^T$, is it possible to obtain a diagonal matrix,

$ \left[\begin{array}{c c c c c} x_1 & 0 & 0 & \dots & 0\\ 0 & x_2 & 0 & \dots & 0\\ 0 & 0 & x_3 & \dots & 0\\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \dots & x_n\\ \end{array} \right] $

using matrix operations (like multiplication and/or addition with identity matrix etc)? This seems trivial, but I am unable to work it out!

I need to do this for automation of process in Maxima, so that I don't have to manually type in the elements diagonally. Thanks.


EDIT:

I recently found a direct function diag_matrix(x1,x2,x3,...) in Maxima. Which means that if we have a list [x1, x2, x3], we can use apply(diag_matrix, [x1, x2, x3]). I am not sure if it is introduced in a recent version or it existed before I posted this question.

$\endgroup$
2
  • 4
    $\begingroup$ If you allow the elementwise/Hadamard product $\odot$ as a standard operation, then using the all-ones vector and the identity matrix yields $${\rm Diag}(x) = I\odot(x{\tt1}^T)$$ Or if you allow higher-order tensors, then $\;{\rm Diag}(x) = {\cal H}x\;$ where $$\eqalign{ {\cal H}_{ijk} &= \begin{cases} {\tt1}\quad{\rm if}\;\;i=j=k \\ {\tt0}\quad{\rm otherwise} \\ \end{cases} \\ }$$ The tensor can be calculated as a sparse array, list comprehension or [Iverson bracket] $\endgroup$
    – greg
    Mar 29, 2021 at 11:40
  • 1
    $\begingroup$ I recently found a direct function diag_matrix(x1,x2,x3,...) in maxima. I am not sure if it is introduced in a recent version or it existed before I posted this question. $\endgroup$ Aug 18, 2021 at 16:18

5 Answers 5

23
$\begingroup$

$$\operatorname{diag} (\mathbf{x}) = \sum_{i=1}^n\mathbf{e}_i'\mathbf{x}\mathbf{e}_i\mathbf{e}_i'$$

Where $\mathbf{e}_i$ is the i-th basis vector of $\mathbb{R}^n$ and $'$ denotes the transpose.

$\endgroup$
6
  • $\begingroup$ Could you explain a source or derivation for this? Also i think you have an extra $e_i '$ at the start of the sum, not sure if that is intended, but idk how else $d/dx_i [diag(x)] = e_i e_i '$ $\endgroup$
    – John D
    Sep 9, 2021 at 10:21
  • $\begingroup$ or is $e_i ' x \equiv x_i$? $\endgroup$
    – John D
    Sep 9, 2021 at 10:30
  • $\begingroup$ I think your diag(x) returns a scalar not a matrix like the question asked... $\endgroup$
    – John D
    Sep 9, 2021 at 10:43
  • 1
    $\begingroup$ $e_i'x$ is indeed equal to $x_i$ and $M=e_i e_i'$ is a matrix where there is only $(M)_{ii} = 1$. This does return a diagonal matrix. $\endgroup$ Sep 9, 2021 at 10:44
  • $\begingroup$ Thank you, i see it now! $\endgroup$
    – John D
    Sep 9, 2021 at 10:47
11
$\begingroup$

I thought about this, and the best I can come up with is the following. It's about as fast as the standard matlab diag() function on small matrices, but I wasn't particularly rigorous. Anyway:

$$ v = v_i \in \mathbb{R}^n \\ D = diag(v) = D_{ii} \in \mathbb{R}^{n \times n} \\ D = \textbf{I}_n \cdot \left( \textbf{1}_n^T \otimes v \right) $$

In Matlab, this can be written as follows:

>> v = sym('v',[5 1])
D = eye(length(v)) .* kron( ones(length(v),1)',v )
v =
 v1
 v2
 v3
 v4
 v5
D =
[ v1,  0,  0,  0,  0]
[  0, v2,  0,  0,  0]
[  0,  0, v3,  0,  0]
[  0,  0,  0, v4,  0]
[  0,  0,  0,  0, v5]
$\endgroup$
2
  • $\begingroup$ Can you explain your notations? Is $I_n$ the identity matrix? $\endgroup$
    – user99914
    Nov 27, 2017 at 21:57
  • $\begingroup$ Sorry. Yes,$\textbf{I}_n$ is the identity matrix of size $n$, $\textbf{1}_n$ is a vector of 1's, $v$ is the input vector, $D$ is the output diagonal. The Kronecker tensor product..if A is an m-by-n matrix and B is a p-by-q matrix, then kron(A,B) is an mp-by-nq matrix formed by taking all possible products between the elements of A and the matrix B. So taking the kronecker product of a row of 1's and a column vector effectively copies that column vector into every cell of the $\textbf{1}_n^T$ row vector. The dot product between an identity matrix and this resultant zeros the off diag. $\endgroup$
    – Ronen
    Dec 5, 2017 at 1:43
3
$\begingroup$

I cannot replicate @Ronen's code in python. Instead, I just use the outer product:

import numpy as np

np.identity(len(x)) * np.outer(np.ones(len(x)), x)

where * is element by element multiplication

$\endgroup$
2
  • $\begingroup$ n = len(x); np.eye(n) * np.kron(np.ones(n)[:, np.newaxis], x) $\endgroup$ Sep 27, 2019 at 18:53
  • $\begingroup$ np.multiply(x,np.identity(x.size)) $\endgroup$
    – moonman239
    Feb 26 at 21:49
2
$\begingroup$

Given a vector x, and you would like to build the diagonal matrix from it: Another mathematical operation could be the so called "hadamard product". It does basically element-wise multiplication of all elements. On order to do so, you need first to build a matrix out of the vector x. That is, use the outer product with another vector which contains only 1 entries: x * [1,1,1,1,1] = tempMatrix

Now apply the hadamard multiplication to this tempMatrix with the identity matrix

Most CAS packages like matlab, mathematica, and probably maxima aswell, offer an operator for the hadamard product In Matlab you would write: eye(5) .* (x * ones(1,5)) or simply diag(x), which does the same.

In maxima you would write ident(5) * (x.[1,1,1,1,1])

$\endgroup$
1
  • $\begingroup$ There is a typo in the Maxima solution, it should be ident(5) * (x*[1,1,1,1,1]), but there is an even simpler solution if the vector is defined as a list, see math.stackexchange.com/a/4226705/412495 $\endgroup$
    – mmj
    Aug 17, 2021 at 15:20
1
$\begingroup$

In Maxima, if you define the vector as a list (i.e. x: [x1,x2,x3,..,xn]) you obtain the diagonal matrix with

ident(n)*x

or, even better, with (thanks to Sourabh Bhat for pointing out)

diag_matrix(x1,x2,...,xn)
$\endgroup$
1
  • 1
    $\begingroup$ There is a direct method actually called diag_matrix(x1,x2,x3). I am not sure if it is introduced recently or existed before I posted this question. $\endgroup$ Aug 18, 2021 at 16:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .