# Random Orthogonal Matrices

**URL:** <https://discourse.julialang.org/t/random-orthogonal-matrices/9779>\
**Category:** Optimization (Mathematical)\
**Created:** [March 17, 2018, 11:56pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779 "2018-03-17T23:56:27Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [March 17, 2018, 11:56pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/1 "2018-03-17T23:56:27Z")

</div>

dear julia experts—has anyone already written a random orthogonal matrix generator for square matrices?

Is the right way to do this generating a random normal matrix first and then running a Gram-Schmidt orthogonalization? (is this somewhere in Julia already, so that I won’t rewrite the wheel)?

pointers appreciated. regards, /iaw

---

<div class="post-metadata">

**Author:** ![abelsiqueira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abelsiqueira/32/47269_2.png) [@abelsiqueira](https://discourse.julialang.org/u/abelsiqueira)\
**Post date:** [March 18, 2018, 12:17am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/2 "2018-03-18T00:17:30Z")

</div>

You can generate a random orthogonal matrix `Q` with

```julia
A = rand(n,n)
Q, R = qr(A)

```

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [March 18, 2018, 1:57am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/3 "2018-03-18T01:57:18Z")

</div>

mille grazie. this was too easy!

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [March 18, 2018, 2:39am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/4 "2018-03-18T02:39:38Z")

</div>

Abel’s solution gives you a more-or-less random matrix which happens to be orthogonal. (Nothing wrong with that, if that’s all you need.)

If you need a random draw from the uniform distribution over the space of orthogonal matrices of rank `n`, I think you want something like

```julia
using RandomMatrices
Q = rand(Haar(1),n) 
# or randfast(Haar(1),n) if you are impatient and not fastidious

```

I remember being annoyed at how hard this was to find.

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [March 18, 2018, 2:54am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/5 "2018-03-18T02:54:10Z")

</div>

even better indeed. thank you.

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [March 18, 2018, 7:26pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/6 "2018-03-18T19:26:38Z")

</div>

> [@Ralph\_Smith](#):
>
> Q = rand(Haar(1),n)

the RandomMatrices installs in 0.6.2, but the brews for macOS abort somewhere, and there are deprecation warnings in the RandomMatrices code (e.g., use exp.() instead of exp() ). so the install and the code could use some tender care.

I am looking at the documentation. I am way over my head on the underlying math.

What I really want is K random directions with maximum distances in N dimensions (N\<=K). So, if I have 2 directions and I want 4 directions, it would be a rotate of (1,0),(0,1),(1,1),(-1,1). If by any chance this is already in this package, please let me know. Otherwise, please ignore.

I am definitely ok with what I know and what I have. I can draw two matrices, and hope that they will not happen to be highly correlated. It’s a little less efficient, but it will do.

regards,

/iaw

---

<div class="post-metadata">

**Author:** ![simonbyrne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simonbyrne/32/19_2.png) [@simonbyrne](https://discourse.julialang.org/u/simonbyrne)\
**Post date:** [March 18, 2018, 9:59pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/7 "2018-03-18T21:59:29Z")

</div>

An easy way to draw from the Haar measure is to take the QR of a matrix of iid random normals, with `R` constrained to have a positive diagonal:

```julia
Q,R = qr(randn(m,n))
O = Q*Diagonal(sign.(diag(R)))

```

There are even faster ways to do this: see [Orthogonal matrix - Wikipedia](https://en.wikipedia.org/wiki/Orthogonal_matrix#Randomization)

---

<div class="post-metadata">

**Author:** ![Andrea\_Vigliotti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrea_vigliotti/32/7635_2.png) [@Andrea\_Vigliotti](https://discourse.julialang.org/u/Andrea_Vigliotti)\
**Post date:** [January 2, 2021, 9:26am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/8 "2021-01-02T09:26:17Z")

</div>

this is nice!

---

<div class="post-metadata">

**Author:** ![fph](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fph/32/17159_2.png) [@fph](https://discourse.julialang.org/u/fph)\
**Post date:** [January 2, 2021, 11:09am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/9 "2021-01-02T11:09:05Z")

</div>

> [@abelsiqueira](#):
>
> You can generate a random orthogonal matrix `Q` with
> 
> ```julia
> A = rand(n,n)
> Q, R = qr(A)
> 
> ```

Note that this answer, which is currently marked as the accepted solution, does not produce uniform (Haar) distributed answers. For instance, it will always produce Q matrices with elements of the same sign in the first column. Simonbyrne’s answer is the correct one.

Another remark is that (Julia’s Householder-based) QR is more stable than Gram-Schmidt which OP was considering.

---

<div class="post-metadata">

**Author:** ![rajnrao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rajnrao/32/20637_2.png) [@rajnrao](https://discourse.julialang.org/u/rajnrao)\
**Post date:** [January 2, 2021, 1:12pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/10 "2021-01-02T13:12:48Z")

</div>

Indeed — see figure 4.1 of

> **[Acta05rmt.pdf](https://rajrao.engin.umich.edu/Acta05rmt.pdf)**

for a quick sim on how to verify what @fph shared.

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [May 12, 2024, 5:40pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/11 "2024-05-12T17:40:00Z")

</div>

That link is dead.Is there an updated version available?

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [May 13, 2024, 1:04am UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/12 "2024-05-13T01:04:57Z")

</div>

A. Edelman and N.R. Rao. Random matrix theory. Acta Numerica, 14(233-297):139, 2005.

> **[random\_matrix\_theory.pdf](https://math.mit.edu/~edelman/publications/random_matrix_theory.pdf)**
>
> 567.61 KB

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [May 13, 2024, 12:15pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/13 "2024-05-13T12:15:06Z")

</div>

In the accepted solution, Q is a m\times m matrix. Is the distribution of Q independent of n? If not, what is the dependency of Q on n?

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [May 13, 2024, 1:07pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/14 "2024-05-13T13:07:33Z")

</div>

```julia
A = rand(m,n)
Q, R = qr(A)

```

with m \geq n will produce a random m \times n Q with orthonormal columns taken from the same measure as in the square case. The QR algorithm works sequentially on the columns of A to build corresponding columns of Q and R. So the first n columns of Q and R will be the same as they would if A were extended to be square with A\_{ij}, j \leq n held constant.

---

<div class="post-metadata">

**Author:** ![jamblejoe](https://avatars.discourse-cdn.com/v4/letter/j/ee7513/32.png) [@jamblejoe](https://discourse.julialang.org/u/jamblejoe)\
**Post date:** [May 13, 2024, 2:30pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/15 "2024-05-13T14:30:11Z")

</div>

Thank you very much for your answer! Extrapolating implies that for increasing n once m\le n, the Q matrix does not change anymore? Hence, with focus on sampling Q m\times m-matrices, there is no reason to go beyond m=n?

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [May 14, 2024, 1:48pm UTC](https://discourse.julialang.org/t/random-orthogonal-matrices/9779/16 "2024-05-14T13:48:29Z")

</div>

I recently digged into methods of uniform sampling from the group of unit quaternions, and I stumbled upon this good reference, that suggests a method to ensure that the probability distribution of the generated orthogonal matrix is the Haar measure: Francesco Mezzadri: [How to generate random matrices from the classical compact groups](http://www.ams.org/notices/200705/fea-mezzadri-web.pdf), Notices Amer. Math. Soc. 54(5), 592–604, 2007.
