Showing posts with label linear algebra. Show all posts
Showing posts with label linear algebra. Show all posts

Thursday, March 3, 2011

3D to 2D vector?



I was just curious to see some mathematical approach to justify the transformation of a 3D vector to 2D vector in the following way:
x' = y-x
y' = z-x ... ... (1)

This is quite simple and obvious, that the mapping can be performed (as shown below). Now the question is, why do we do that? As the exact answer is unknown to me, my answer is, it will be easier to handle linear systems of certain type, i.e. involving 3D vectors, as we can change them to systems of 2D vectors easily (from a programming perspective).

Here, I will denote [x, y, z] format as a 3D vector with components x, y, z and [x', y'] as a 2D vector with components x', y' where, [x, y, z] and [x', y'] satisfies the transformation showed in (1).

Lets assume we have a linear system consisting of 2 such 3D vectors:
α[x1, y1, z1] + β[x2, y2, z2] = [γ1, γ2, γ3] ... (2)

Now if we apply the transformation from (1), we get a system of 2D vectors as follows:
α[y1-x1, z1-x1] + β[y2-x2, z2-x2] = [γ21, γ31] ... (3)

Now lets see if we can show (2) and (3) to be equivalent:

From (2), we get 3 equations:
αx1 + βx2 = γ1 ... (I)
αy1 + βy2 = γ2 ... (II)
αz1 + βz2 = γ3 ... (III)

Similarly from (3) we get 2 equations:
α(y1-x1) + β(y2-x2) = γ21
α(z1-x1) + β(z2-x2) = γ31

It is quite obvious to see that, we can get the later 2 equations from the first set, by subtracting (I) from both (II) and (III).

Similarly, this can be extended to a more general format:
α1[x1, y1, z1] + α2[x2, y2, z2] + ... ... + αn[xn, yn, zn] = [γ1, γ2, γ3]

Thus, we can conclude, (2) and (3) represents the same system. And, following this way, we can always reduce the dimensions of vectors involved in a linear system.

Additionally, if γ1 = γ2 = γ3 = γ then clearly, this is more simple, as in 2D, the vector in right side will be just [0, 0].

Actually, one of my desperate friend hit me today with this, as, if we can't get the answer, he will suicide... So, this is what I told him. Unfortunately, I am not from a mathematics background, and therefore, I may have abused some mathematical terms, sorry for that, and if anyone can tell me something more details and more general about it (what should I call this? I don't know either), or, if you find this post is totally wrong, please, save my friend from committing suicide by letting me know :p

Thank you!

Friday, December 11, 2009

Gauss–Jordan Elimination


Gauss–Jordan Elimination in C++


This is my first attempt to solve linear systems with unique solutions in O(N3).


Algorithm:
1. Read augmented matrix for the system.
2. Perform Gaussian Elimination to get the matrix in row echelon form.
3. Transform the matrix to reduced row echelon form.
4. Write results.

Preview:

[click for a clear view]

My C++ solution (change MAX to desired size, it is the maximum limit of how many equations it can handle, change the macro DEBUG to "if(1)" if you want to see the intermediate steps):

#include <iostream>
#include <cstdlib>
#include <cassert>
#include <algorithm>
using namespace std;

#define DEBUG if(0)
#define MAX 5

struct MAT {
int R[MAX+1];
} M[MAX];

int N;

int gcd(int a, int b) {
while(b) b ^= a ^= b ^= a %= b;
return a;
}

bool comp(MAT A, MAT B) {
for(int k=0; k<N; k++) {
if(A.R[k] > B.R[k]) return true;
if(A.R[k] < B.R[k]) return false;
}
return true;
}

void print(void) {
int i, j;
cout << "..." << endl;
for(i=0; i<N; i++) {
for(j=0; j<N; j++) cout << M[i].R[j] << '\t';
cout << M[i].R[j] << endl;
}
cout << "..." << endl;
}

void modify(MAT &A, MAT B, int a, int b) {
for(int r=0; r<=N; r++) A.R[r] = a*B.R[r] - b*A.R[r];
}

void eliminate(void) {
int i, g, k;
for(i=0; i<N-1; i++) {
if(!M[i].R[i]) {
sort(&M[i], M+N, comp);
assert(M[i].R[i]);
}
for(k=i+1; k<N; k++) {
g = gcd(abs(M[i].R[i]), abs(M[k].R[i]));
modify(M[k], M[i], M[k].R[i]/g, M[i].R[i]/g);
}
DEBUG print();
}
}

void reduce(void) {
int i, g, k;
for(i=N-1; i; i--) {
for(k=i-1; k>=0; k--) {
g = gcd(abs(M[i].R[i]), abs(M[k].R[i]));
modify(M[k], M[i], M[k].R[i]/g, M[i].R[i]/g);
}
DEBUG print();
}
}

void printsol(void) {
double h, l;
cout << "Solve for " << N << " variables:" << endl;
for(int i=0; i<N; i++) {
assert(M[i].R[i]);
h = M[i].R[i];
l = M[i].R[N];
cout << 'x' << i+1 << " = " << l/h << endl;
}
cout << "..." << endl;
}

int main(void) {
int i, j, g;
while(cin >> N) {
if(!N) break;
memset(M, 0, sizeof(M));
for(i=0; i<N; i++) {
for(j=0; j<N; j++) cin >> M[i].R[j];
cin >> M[i].R[j];
for(j=g=0; j<=N; j++) g = gcd(abs(M[i].R[j]), g);
for(j=0; j<=N; j++) M[i].R[j] /= g;
}
eliminate();
reduce();
printsol();
}
return 0;
}

However, I'm trying to do it in a more efficient way. I'll post that when I'm done.


Sunday, July 12, 2009

Largest impossible score


Problem:
If two possible points in a game is p and q, what is the largest impossible score of the game which can't be achieved? Or it can't be determined? In other words, for integers p, q ≥ 0, what is the maximum number m which can't be written as a linear combination of p, q, i.e. px + qy, where, x, y ≥ 0.

Solution:
The score can only be determined when p and q are co-primes, i.e. g = GCD(a,b) = 1. Otherwise, we can only make the multiples of g and the remaining numbers can't be made which means the maximum number can't be determined, or infinite! This also covers the case if exactly one of p or q is 0.

One other required condition is p,q > 1. If anyone of p or q is 1, there is no such score which can't be achieved, i.e. answer will be 0. If p and q both are 0, we can't even make any score...

Now, we can arrange the numbers from 0 to p*q-1 in a rectangular array as follows:

0 1 ....... q-1
q q+1 ....... 2q-1
... ... ....... ...
... ... ....... ...
(p-1)q (p-1)(q-1) ....... pq-1

For example, if p = 3 and q = 7, we have the following table:

(0) 1 2 (3) 4 5 (6)
7 8 (9) 10 11 (12) 13
14 (15) 16 17 (18) 19 20

We have circled the multiples of p in the above table and claim these observations:

  • There will be q circled numbers. As we have exactly p numbers in each of q columns, so each column will have exactly one circled number, i.e. multiple of p, which implies, there will be a total of q circled number in this table.

  • No two circled numbers are in same same column and there will be only one circled number in any column. For the same reason stated above, exactly one circled number in each column.

  • Any circled number is possible. This is trivial, because, the circled numbers are multiple of one of the two given numbers, i.e. in the form p*x + q*0 or p*0 + q*x.

  • Any number below the circled one in the same column is possible. We have seen any circled number is possible. A circled number is the first multiple of p in the respective column, i.e. n*p, where n ≥1, so the following numbers in the column will be: n*p + q, n*p + 2*q. n*p + 3*q, ... ... ... which are always possible.

  • Any number above the circled one in the same column is impossible. This is also explained in the previous step. As any circled number in a column is the first one which is a multiple of one element, the number above this one will be neither the multiple of any of the two numbers. So it is impossible.

  • Any number ≥ p*q is possible. As we complete p rows of the table with q columns, we already have one circled number in each column, so, any number > p*q-1 (i.e. the last element of the table) will be surely following any of the q circled numbers, so any number starting from the p+1th row, starting from p*q will be possible.


Now considering all these observations, we can see that, largest impossible number is the number just above the last circled number. The last circled number is p*q-p, i.e. 21-3 = 18 and number above it is (p*q-p)-q, i.e. 18-7 = 11. So in general, largest impossible number is: p*q - p - q.

Conclusion:
If you are given p, q :: two positive numbers, the largest number, m, which can't be expressed as a linear combination of p, q i.e. in the form px + qy, where x and y are two non-negative numbers, is p * q - p - q, when p, q > 1 and GCD(p, q) is 1 i.e. p, q are co-primes.