# Code to produce orthogonal rows in a N* N matrices

4 views (last 30 days)
Sudhir Kumar on 28 Jun 2020
Edited: John D'Errico on 28 Jun 2020
How to produce N*N matrix where 1st row is ones(1,N) and rest of the rows are orthogonal to each of the row.

David Goodmanson on 28 Jun 2020
Hi Sudhir,
are there any conditions on the vectors that constitute the N-1 bases vectors? For example, do the vector components have to be integers?
Sudhir Kumar on 28 Jun 2020
No no it can be any number but has to real number thats all
Sudhir Kumar on 28 Jun 2020
Please provide any code if you have in matlab

John D'Errico on 28 Jun 2020
Edited: John D'Errico on 28 Jun 2020
Not that hard. First check, is this homework? Hmm. Highly unlikely, since I had to think for at least a second about how to solve it. If your teacher gave you an interesting homework assignment then they caught me. ;-)
I presume the request is to find different, distinct orthogonal matrices every time. Otherwise the answer is trivial. Thus, if you just want the same result every time, then:
% Choose N:
N = 6;
A = ones(1,N);
A = [A;null(A)'];
The result is N linearly independent orthogonal rows, the first row being all ones. A has the property that A*A' will produce a result indicating the rows are indeed orthogonl. Be careful:
A
A =
1 1 1 1 1 1
-0.40825 0.88165 -0.11835 -0.11835 -0.11835 -0.11835
-0.40825 -0.11835 0.88165 -0.11835 -0.11835 -0.11835
-0.40825 -0.11835 -0.11835 0.88165 -0.11835 -0.11835
-0.40825 -0.11835 -0.11835 -0.11835 0.88165 -0.11835
-0.40825 -0.11835 -0.11835 -0.11835 -0.11835 0.88165
>> A*A'
ans =
6 -8.3267e-17 -1.1102e-16 -8.3267e-17 -4.1633e-17 0
-8.3267e-17 1 1.3046e-17 1.3046e-17 7.8421e-18 1.18e-18
-1.1102e-16 1.3046e-17 1 2.6924e-17 7.8421e-18 1.18e-18
-8.3267e-17 1.3046e-17 2.6924e-17 1 7.8421e-18 1.18e-18
-4.1633e-17 7.8421e-18 7.8421e-18 7.8421e-18 1 1.18e-18
0 1.18e-18 1.18e-18 1.18e-18 1.18e-18 1
As you can see, because you insisted the first row must be all ones, it has not been made to have unit 2-norm. There for the (1,1) element of A*A' wil not be 1, but always N. Worse, A'*A will not be even close to an identity. But you insisted the matrix have a unit first row. So if I then normalize the first row of A...
A(1,:) = A(1,:)/norm(A(1,:))
A =
0.40825 0.40825 0.40825 0.40825 0.40825 0.40825
-0.40825 0.88165 -0.11835 -0.11835 -0.11835 -0.11835
-0.40825 -0.11835 0.88165 -0.11835 -0.11835 -0.11835
-0.40825 -0.11835 -0.11835 0.88165 -0.11835 -0.11835
-0.40825 -0.11835 -0.11835 -0.11835 0.88165 -0.11835
-0.40825 -0.11835 -0.11835 -0.11835 -0.11835 0.88165
>> A'*A
ans =
1 5.6919e-17 2.9163e-17 5.6919e-17 9.8552e-17 1.2319e-16
5.6919e-17 1 1.3046e-17 1.3046e-17 7.8421e-18 1.18e-18
2.9163e-17 1.3046e-17 1 2.6924e-17 7.8421e-18 1.18e-18
5.6919e-17 1.3046e-17 2.6924e-17 1 7.8421e-18 1.18e-18
9.8552e-17 7.8421e-18 7.8421e-18 7.8421e-18 1 1.18e-18
1.2319e-16 1.18e-18 1.18e-18 1.18e-18 1.18e-18 1
>> A*A'
ans =
1 -5.6919e-17 -2.9163e-17 -5.6919e-17 -9.8552e-17 -1.2319e-16
-5.6919e-17 1 1.3046e-17 1.3046e-17 7.8421e-18 1.18e-18
-2.9163e-17 1.3046e-17 1 2.6924e-17 7.8421e-18 1.18e-18
-5.6919e-17 1.3046e-17 2.6924e-17 1 7.8421e-18 1.18e-18
-9.8552e-17 7.8421e-18 7.8421e-18 7.8421e-18 1 1.18e-18
-1.2319e-16 1.18e-18 1.18e-18 1.18e-18 1.18e-18 1
Now both products are essentially identity matrices to within floating point trash. The problem is, this result is not random in any sense. And I gather you wanted random. That is also not difficult, and a simple extension. Do you see how? The basic trick is still the same. Still not hard.
N = 4;
A = ones(1,N);
V2 = randn(1,N); % a random start
V2 = V2/norm(V2);
V2 = V2 - A*dot(V2,A)/norm(V2)/N;
A = [A;V2/norm(V2)];
A = [A;null(A)'];
This yields a different matrix each time with the desired property. Note that again, you needed to scale the first row to have unit norm if you will try to form A'*A to test. Here, with N == 4, I get the expected result, and it will be a new such matrix every time, because the SECOND row is chosen randomly.
A
A =
1 1 1 1
0.63227 -0.59478 0.3318 -0.36929
-0.5759 -0.07093 0.79992 -0.15308
-0.13625 -0.62546 -0.0065307 0.76824
A*A'
ans =
4 2.2204e-16 2.7756e-16 5.5511e-17
2.2204e-16 1 4.1633e-17 4.1633e-17
2.7756e-16 4.1633e-17 1 -1.3878e-17
5.5511e-17 4.1633e-17 -1.3878e-17 1
As I said, easy enough to solve. The trick is to choose one new vector as the second row randomly. Then employ one step of a Gram-Schmidt process to make it orthogonal to the first row. Then use null to produce the other N-2 rows.
Just thinking, that points out an obvious alternative, but it is no better really. That is, I could have generated N-1 random rows. Then subtract off the component of each row that has non-zero projection on the vector ones(1,N). Finally, use orth to make those N-1 rows orthongonal to each other. As I said. No better, and probably slightly slower to run for large N.
If it was homeowrk, then I apologize to your teacher. :)