Code to produce orthogonal rows in a N* N matrices
3 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Sudhir Kumar
il 28 Giu 2020
Modificato: John D'Errico
il 28 Giu 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.
6 Commenti
Risposta accettata
John D'Errico
il 28 Giu 2020
Modificato: John D'Errico
il 28 Giu 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. :)
0 Commenti
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!