44

I have a row vector A, A = [a1 a2 a3 ..... an] and I would like to create a diagonal matrix, B = diag(a1, a2, a3, ....., an) with the elements of this row vector. How can this be done in Python?

UPDATE

This is the code to illustrate the problem:

import numpy as np
a = np.matrix([1,2,3,4])
d = np.diag(a)
print (d)

the output of this code is [1], but my desired output is:

[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]
Tom Kurushingal
  • 6,086
  • 20
  • 54
  • 86

4 Answers4

71

You can use diag method:

import numpy as np

a = np.array([1,2,3,4])
d = np.diag(a)
# or simpler: d = np.diag([1,2,3,4])

print(d)

Results in:

[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]

If you have a row vector, you can do this:

a = np.array([[1, 2, 3, 4]])
d = np.diag(a[0])

Results in:

[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]

For the given matrix in the question:

import numpy as np
a = np.matrix([1,2,3,4])
d = np.diag(a.A1)
print (d)

Result is again:

[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]
user2357112
  • 260,549
  • 28
  • 431
  • 505
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • Could you try changing a from an array to a matrix. – Tom Kurushingal Feb 19 '15 at 06:11
  • I think it It would be easier if you could just edit your question and provide actual code example that you have, example input and expected output, errors you get etc. Otherwise its a guessing game. – Marcin Feb 19 '15 at 06:14
10

I suppose you could also use diagflat:

import numpy
a = np.matrix([1,2,3,4])
d = np.diagflat(a)
print (d)

Which like the diag method results in

[[1 0 0 0]
 [0 2 0 0]
 [0 0 3 0]
 [0 0 0 4]]

but there's no need for flattening with .A1

Bokee
  • 101
  • 1
  • 3
1

Another solution could be:

import numpy as np
a = np.array([1,2,3,4])
d = a * np.identity(len(a))

As for performances for the various answers here, I get with timeit on 100000 repetitions:

  1. np.array and np.diag (Marcin's answer): 2.18E-02 s
  2. np.array and np.identity (this answer): 6.12E-01 s
  3. np.matrix and np.diagflat (Bokee's answer): 1.00E-00 s
jeannej
  • 1,135
  • 1
  • 9
  • 23
0

Assuming you are working in numpy based on your tags, this will do it:

import numpy
def make_diag( A ):
    my_diag = numpy.zeroes( ( 2, 2 ) )
    for i, a in enumerate( A ):
        my_diag[i,i] = a
    return my_diag

enumerate( LIST ) creates an iterator over the list that returns tuples like:

( 0, 1st element), ( 1, 2nd element), ... ( N-1, Nth element )

deadcode
  • 2,226
  • 1
  • 20
  • 29