Вы можете использовать матрицы Домохозяина, чтобы сделать это.См., Например, http://en.wikipedia.org/wiki/Householder_reflection и http://en.wikipedia.org/wiki/QR_decomposition
. Можно найти матрицу домохозяина Q
, так что Q*u = e_1
(где e_k
- это вектор, равный 0, кроме 1 вk-е место) Тогда, если f_k = Q*e_k
, f_k
образуют ортогональный базис и f_1 = u
.(Поскольку Q*Q = I
, а Q ортогональна.)
Все эти разговоры о матрицах могут создать впечатление, что процедура будет дорогой, но это не так.Например, эта функция C, учитывая, что вектор длины 1 возвращает массив с требуемой базой в порядке столбцов, т.е. j-й компонент i-го вектора содержится в b [j + dim * i]
double* make_basis( int dim, const double* v)
{
double* B = calloc( dim*dim, sizeof * B);
double* h = calloc( dim, sizeof *h);
double f, s, d;
int i, j;
/* compute Householder vector and factor */
memcpy( h, v, dim*sizeof *h);
s = ( v[0] > 0.0) ? 1.0 : -1.0;
h[0] += s;
f = s/(s+v[0]);
/* compute basis */
memcpy( B, v, dim * sizeof *v); /* first one is v */
/* others by applying Householder matrix */
for( i=1; i<dim; ++i)
{ d = f*h[i];
for( j=0; j<dim; ++j)
{ B[dim*i+j] = (i==j) - d*h[j];
}
}
free( h);
return B;
}