|
Packit |
67cb25 |
/* multilarge/test.c
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Copyright (C) 2015 Patrick Alken
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
67cb25 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
67cb25 |
* the Free Software Foundation; either version 3 of the License, or (at
|
|
Packit |
67cb25 |
* your option) any later version.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
67cb25 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
67cb25 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
67cb25 |
* General Public License for more details.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
67cb25 |
* along with this program; if not, write to the Free Software
|
|
Packit |
67cb25 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include <config.h>
|
|
Packit |
67cb25 |
#include <stdlib.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_test.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_multifit.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_multilarge.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_blas.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_rng.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_linalg.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_ieee_utils.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void test_random_matrix_orth(gsl_matrix *m, const gsl_rng *r);
|
|
Packit |
67cb25 |
static void test_random_matrix_ill(gsl_matrix *m, const gsl_rng *r);
|
|
Packit |
67cb25 |
static void test_random_vector(gsl_vector *v, const gsl_rng *r,
|
|
Packit |
67cb25 |
const double lower, const double upper);
|
|
Packit |
67cb25 |
static void test_random_matrix(gsl_matrix *m, const gsl_rng *r,
|
|
Packit |
67cb25 |
const double lower, const double upper);
|
|
Packit |
67cb25 |
static void test_random_vector_noise(const gsl_rng *r, gsl_vector *y);
|
|
Packit |
67cb25 |
static void test_compare_vectors(const double tol, const gsl_vector * a,
|
|
Packit |
67cb25 |
const gsl_vector * b, const char * desc);
|
|
Packit |
67cb25 |
static void test_multifit_solve(const double lambda, const gsl_matrix * X,
|
|
Packit |
67cb25 |
const gsl_vector * y, const gsl_vector * wts,
|
|
Packit |
67cb25 |
const gsl_vector * diagL, const gsl_matrix * L,
|
|
Packit |
67cb25 |
double *rnorm, double *snorm, gsl_vector * c);
|
|
Packit |
67cb25 |
static void test_multilarge_solve(const gsl_multilarge_linear_type * T, const double lambda,
|
|
Packit |
67cb25 |
const gsl_matrix * X, const gsl_vector * y, gsl_vector * wts,
|
|
Packit |
67cb25 |
const gsl_vector * diagL, const gsl_matrix * L,
|
|
Packit |
67cb25 |
double *rnorm, double *snorm, gsl_vector * c);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* generate random square orthogonal matrix via QR decomposition */
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_random_matrix_orth(gsl_matrix *m, const gsl_rng *r)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t M = m->size1;
|
|
Packit |
67cb25 |
gsl_matrix *A = gsl_matrix_alloc(M, M);
|
|
Packit |
67cb25 |
gsl_vector *tau = gsl_vector_alloc(M);
|
|
Packit |
67cb25 |
gsl_matrix *R = gsl_matrix_alloc(M, M);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
test_random_matrix(A, r, -1.0, 1.0);
|
|
Packit |
67cb25 |
gsl_linalg_QR_decomp(A, tau);
|
|
Packit |
67cb25 |
gsl_linalg_QR_unpack(A, tau, m, R);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_free(A);
|
|
Packit |
67cb25 |
gsl_matrix_free(R);
|
|
Packit |
67cb25 |
gsl_vector_free(tau);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* construct ill-conditioned matrix via SVD */
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_random_matrix_ill(gsl_matrix *m, const gsl_rng *r)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t M = m->size1;
|
|
Packit |
67cb25 |
const size_t N = m->size2;
|
|
Packit |
67cb25 |
gsl_matrix *U = gsl_matrix_alloc(M, M);
|
|
Packit |
67cb25 |
gsl_matrix *V = gsl_matrix_alloc(N, N);
|
|
Packit |
67cb25 |
gsl_vector *S = gsl_vector_alloc(N);
|
|
Packit |
67cb25 |
gsl_matrix_view Uv = gsl_matrix_submatrix(U, 0, 0, M, N);
|
|
Packit |
67cb25 |
const double smin = 16.0 * GSL_DBL_EPSILON;
|
|
Packit |
67cb25 |
const double smax = 10.0;
|
|
Packit |
67cb25 |
const double ratio = pow(smin / smax, 1.0 / (N - 1.0));
|
|
Packit |
67cb25 |
double s;
|
|
Packit |
67cb25 |
size_t j;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
test_random_matrix_orth(U, r);
|
|
Packit |
67cb25 |
test_random_matrix_orth(V, r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* compute U * S */
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
s = smax;
|
|
Packit |
67cb25 |
for (j = 0; j < N; ++j)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector_view uj = gsl_matrix_column(U, j);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_scale(&uj.vector, s);
|
|
Packit |
67cb25 |
s *= ratio;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* compute m = (U * S) * V' */
|
|
Packit |
67cb25 |
gsl_blas_dgemm(CblasNoTrans, CblasTrans, 1.0, &Uv.matrix, V, 0.0, m);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_free(U);
|
|
Packit |
67cb25 |
gsl_matrix_free(V);
|
|
Packit |
67cb25 |
gsl_vector_free(S);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_random_vector(gsl_vector *v, const gsl_rng *r,
|
|
Packit |
67cb25 |
const double lower, const double upper)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
size_t N = v->size;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < N; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector_set(v, i,
|
|
Packit |
67cb25 |
gsl_rng_uniform(r) * (upper - lower) + lower);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_random_matrix(gsl_matrix *m, const gsl_rng *r,
|
|
Packit |
67cb25 |
const double lower, const double upper)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i, j;
|
|
Packit |
67cb25 |
size_t M = m->size1;
|
|
Packit |
67cb25 |
size_t N = m->size2;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < M; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
for (j = 0; j < N; ++j)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_matrix_set(m, i, j,
|
|
Packit |
67cb25 |
gsl_rng_uniform(r) * (upper - lower) + lower);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* generate Vandermonde matrix using equally spaced input points
|
|
Packit |
67cb25 |
* on [0,1] */
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_vander_matrix(gsl_matrix * m)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t M = m->size1;
|
|
Packit |
67cb25 |
const size_t N = m->size2;
|
|
Packit |
67cb25 |
const double dt = 1.0 / (M - 1.0);
|
|
Packit |
67cb25 |
size_t i, j;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < M; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double ti = i * dt;
|
|
Packit |
67cb25 |
double mij = 1.0;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (j = 0; j < N; ++j)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_matrix_set(m, i, j, mij);
|
|
Packit |
67cb25 |
mij *= ti;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_random_vector_noise(const gsl_rng *r, gsl_vector *y)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < y->size; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double *ptr = gsl_vector_ptr(y, i);
|
|
Packit |
67cb25 |
*ptr += 1.0e-3 * gsl_rng_uniform(r);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_compare_vectors(const double tol, const gsl_vector * a,
|
|
Packit |
67cb25 |
const gsl_vector * b, const char * desc)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < a->size; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double ai = gsl_vector_get(a, i);
|
|
Packit |
67cb25 |
double bi = gsl_vector_get(b, i);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(bi, ai, tol, "%s i=%zu", desc, i);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* solve least squares system with multifit SVD */
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_multifit_solve(const double lambda, const gsl_matrix * X,
|
|
Packit |
67cb25 |
const gsl_vector * y, const gsl_vector * wts,
|
|
Packit |
67cb25 |
const gsl_vector * diagL, const gsl_matrix * L,
|
|
Packit |
67cb25 |
double *rnorm, double *snorm, gsl_vector * c)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t n = X->size1;
|
|
Packit |
67cb25 |
const size_t p = X->size2;
|
|
Packit |
67cb25 |
gsl_multifit_linear_workspace *w =
|
|
Packit |
67cb25 |
gsl_multifit_linear_alloc(n, p);
|
|
Packit |
67cb25 |
gsl_matrix *Xs = gsl_matrix_alloc(n, p);
|
|
Packit |
67cb25 |
gsl_vector *ys = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector *cs = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
gsl_matrix *LQR = NULL;
|
|
Packit |
67cb25 |
gsl_vector *Ltau = NULL;
|
|
Packit |
67cb25 |
gsl_matrix *M = NULL;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* convert to standard form */
|
|
Packit |
67cb25 |
if (diagL)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_multifit_linear_wstdform1(diagL, X, wts, y, Xs, ys, w);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if (L)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t m = L->size1;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
LQR = gsl_matrix_alloc(m, p);
|
|
Packit |
67cb25 |
Ltau = gsl_vector_alloc(GSL_MIN(m, p));
|
|
Packit |
67cb25 |
M = (m >= p) ? gsl_matrix_alloc(m, p) : gsl_matrix_alloc(n, p);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_memcpy(LQR, L);
|
|
Packit |
67cb25 |
gsl_multifit_linear_L_decomp(LQR, Ltau);
|
|
Packit |
67cb25 |
gsl_multifit_linear_wstdform2(LQR, Ltau, X, wts, y, Xs, ys, M, w);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_matrix_memcpy(Xs, X);
|
|
Packit |
67cb25 |
gsl_vector_memcpy(ys, y);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multifit_linear_svd(Xs, w);
|
|
Packit |
67cb25 |
gsl_multifit_linear_solve(lambda, Xs, ys, cs, rnorm, snorm, w);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* convert to general form */
|
|
Packit |
67cb25 |
if (diagL)
|
|
Packit |
67cb25 |
gsl_multifit_linear_genform1(diagL, cs, c, w);
|
|
Packit |
67cb25 |
else if (L)
|
|
Packit |
67cb25 |
gsl_multifit_linear_wgenform2(LQR, Ltau, X, wts, y, cs, M, c, w);
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
gsl_vector_memcpy(c, cs);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multifit_linear_free(w);
|
|
Packit |
67cb25 |
gsl_matrix_free(Xs);
|
|
Packit |
67cb25 |
gsl_vector_free(ys);
|
|
Packit |
67cb25 |
gsl_vector_free(cs);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (LQR)
|
|
Packit |
67cb25 |
gsl_matrix_free(LQR);
|
|
Packit |
67cb25 |
if (Ltau)
|
|
Packit |
67cb25 |
gsl_vector_free(Ltau);
|
|
Packit |
67cb25 |
if (M)
|
|
Packit |
67cb25 |
gsl_matrix_free(M);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* solve least squares system with multilarge */
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_multilarge_solve(const gsl_multilarge_linear_type * T, const double lambda,
|
|
Packit |
67cb25 |
const gsl_matrix * X, const gsl_vector * y, gsl_vector * wts,
|
|
Packit |
67cb25 |
const gsl_vector * diagL, const gsl_matrix * L,
|
|
Packit |
67cb25 |
double *rnorm, double *snorm, gsl_vector * c)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t n = X->size1;
|
|
Packit |
67cb25 |
const size_t p = X->size2;
|
|
Packit |
67cb25 |
const size_t nblock = 5;
|
|
Packit |
67cb25 |
const size_t nrows = n / nblock; /* number of rows per block */
|
|
Packit |
67cb25 |
gsl_multilarge_linear_workspace *w =
|
|
Packit |
67cb25 |
gsl_multilarge_linear_alloc(T, p);
|
|
Packit |
67cb25 |
gsl_matrix *Xs = gsl_matrix_alloc(nrows, p);
|
|
Packit |
67cb25 |
gsl_vector *ys = gsl_vector_alloc(nrows);
|
|
Packit |
67cb25 |
gsl_vector *cs = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
gsl_matrix *LQR = NULL;
|
|
Packit |
67cb25 |
gsl_vector *Ltau = NULL;
|
|
Packit |
67cb25 |
size_t rowidx = 0;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (L)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t m = L->size1;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
LQR = gsl_matrix_alloc(m, p);
|
|
Packit |
67cb25 |
Ltau = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_memcpy(LQR, L);
|
|
Packit |
67cb25 |
gsl_multilarge_linear_L_decomp(LQR, Ltau);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
while (rowidx < n)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t nleft = n - rowidx;
|
|
Packit |
67cb25 |
size_t nr = GSL_MIN(nrows, nleft);
|
|
Packit |
67cb25 |
gsl_matrix_const_view Xv = gsl_matrix_const_submatrix(X, rowidx, 0, nr, p);
|
|
Packit |
67cb25 |
gsl_vector_const_view yv = gsl_vector_const_subvector(y, rowidx, nr);
|
|
Packit |
67cb25 |
gsl_vector_view wv;
|
|
Packit |
67cb25 |
gsl_matrix_view Xsv = gsl_matrix_submatrix(Xs, 0, 0, nr, p);
|
|
Packit |
67cb25 |
gsl_vector_view ysv = gsl_vector_subvector(ys, 0, nr);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (wts)
|
|
Packit |
67cb25 |
wv = gsl_vector_subvector(wts, rowidx, nr);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* convert to standard form */
|
|
Packit |
67cb25 |
if (diagL)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_multilarge_linear_wstdform1(diagL, &Xv.matrix, wts ? &wv.vector : NULL,
|
|
Packit |
67cb25 |
&yv.vector, &Xsv.matrix, &ysv.vector, w);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else if (L)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_multilarge_linear_wstdform2(LQR, Ltau, &Xv.matrix, wts ? &wv.vector : NULL,
|
|
Packit |
67cb25 |
&yv.vector, &Xsv.matrix, &ysv.vector, w);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_matrix_memcpy(&Xsv.matrix, &Xv.matrix);
|
|
Packit |
67cb25 |
gsl_vector_memcpy(&ysv.vector, &yv.vector);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multilarge_linear_accumulate(&Xsv.matrix, &ysv.vector, w);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
rowidx += nr;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multilarge_linear_solve(lambda, cs, rnorm, snorm, w);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (diagL)
|
|
Packit |
67cb25 |
gsl_multilarge_linear_genform1(diagL, cs, c, w);
|
|
Packit |
67cb25 |
else if (L)
|
|
Packit |
67cb25 |
gsl_multilarge_linear_genform2(LQR, Ltau, cs, c, w);
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
gsl_vector_memcpy(c, cs);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multilarge_linear_free(w);
|
|
Packit |
67cb25 |
gsl_matrix_free(Xs);
|
|
Packit |
67cb25 |
gsl_vector_free(ys);
|
|
Packit |
67cb25 |
gsl_vector_free(cs);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (LQR)
|
|
Packit |
67cb25 |
gsl_matrix_free(LQR);
|
|
Packit |
67cb25 |
if (Ltau)
|
|
Packit |
67cb25 |
gsl_vector_free(Ltau);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
test_random(const gsl_multilarge_linear_type * T,
|
|
Packit |
67cb25 |
const size_t n, const size_t p,
|
|
Packit |
67cb25 |
const double tol,
|
|
Packit |
67cb25 |
const gsl_rng * r)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const double tol1 = 1.0e3 * tol;
|
|
Packit |
67cb25 |
gsl_matrix *X = gsl_matrix_alloc(n, p);
|
|
Packit |
67cb25 |
gsl_vector *y = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector *c = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
gsl_vector *w = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector *diagL = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
gsl_matrix *Lsqr = gsl_matrix_alloc(p, p);
|
|
Packit |
67cb25 |
gsl_matrix *Ltall = gsl_matrix_alloc(5*p, p);
|
|
Packit |
67cb25 |
gsl_vector *c0 = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
gsl_vector *c1 = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
double rnorm0, snorm0;
|
|
Packit |
67cb25 |
double rnorm1, snorm1;
|
|
Packit |
67cb25 |
char str[2048];
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* generate LS system */
|
|
Packit |
67cb25 |
test_random_matrix_ill(X, r);
|
|
Packit |
67cb25 |
/*test_random_matrix(X, r, -1.0, 1.0);*/
|
|
Packit |
67cb25 |
test_random_vector(c, r, -1.0, 1.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* compute y = X c + noise */
|
|
Packit |
67cb25 |
gsl_blas_dgemv(CblasNoTrans, 1.0, X, c, 0.0, y);
|
|
Packit |
67cb25 |
test_random_vector_noise(r, y);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* random weights */
|
|
Packit |
67cb25 |
test_random_vector(w, r, 0.0, 1.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* random diag(L) */
|
|
Packit |
67cb25 |
test_random_vector(diagL, r, 1.0, 5.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* random square L */
|
|
Packit |
67cb25 |
test_random_matrix(Lsqr, r, -5.0, 5.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* random tall L */
|
|
Packit |
67cb25 |
test_random_matrix(Ltall, r, -10.0, 10.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < 2; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double lambda = pow(10.0, -(double) i);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* unweighted with L = I */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, NULL, NULL, NULL, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, NULL, NULL, NULL, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s unweighted stdform n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* weighted, L = diag(L) */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, w, diagL, NULL, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, w, diagL, NULL, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s weighted diag(L) n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* unweighted, L = diag(L) */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, NULL, diagL, NULL, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, NULL, diagL, NULL, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s unweighted diag(L) n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* weighted, L = square */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, w, NULL, Lsqr, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, w, NULL, Lsqr, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s weighted Lsqr n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* unweighted, L = square */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, NULL, NULL, Lsqr, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, NULL, NULL, Lsqr, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s unweighted Lsqr n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* weighted, L = tall */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, w, NULL, Ltall, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, w, NULL, Ltall, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s weighted Ltall n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* unweighted, L = tall */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
test_multifit_solve(lambda, X, y, NULL, NULL, Ltall, &rnorm0, &snorm0, c0);
|
|
Packit |
67cb25 |
test_multilarge_solve(T, lambda, X, y, NULL, NULL, Ltall, &rnorm1, &snorm1, c1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
sprintf(str, "random %s unweighted Ltall n=%zu p=%zu lambda=%g",
|
|
Packit |
67cb25 |
T->name, n, p, lambda);
|
|
Packit |
67cb25 |
test_compare_vectors(tol, c0, c1, str);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(rnorm1, rnorm0, tol1, "rnorm %s", str);
|
|
Packit |
67cb25 |
gsl_test_rel(snorm1, snorm0, tol, "snorm %s", str);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_free(X);
|
|
Packit |
67cb25 |
gsl_vector_free(y);
|
|
Packit |
67cb25 |
gsl_vector_free(c);
|
|
Packit |
67cb25 |
gsl_vector_free(w);
|
|
Packit |
67cb25 |
gsl_vector_free(diagL);
|
|
Packit |
67cb25 |
gsl_matrix_free(Lsqr);
|
|
Packit |
67cb25 |
gsl_matrix_free(Ltall);
|
|
Packit |
67cb25 |
gsl_vector_free(c0);
|
|
Packit |
67cb25 |
gsl_vector_free(c1);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
main (void)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_rng *r = gsl_rng_alloc(gsl_rng_default);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_ieee_env_setup();
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const double tol1 = 1.0e-8;
|
|
Packit |
67cb25 |
const double tol2 = 1.0e-11;
|
|
Packit |
67cb25 |
const size_t n_vals[] = { 40, 356, 501 };
|
|
Packit |
67cb25 |
const size_t p_vals[] = { 40, 213, 345 };
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < 2; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t n = n_vals[i];
|
|
Packit |
67cb25 |
size_t p = p_vals[i];
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* generate random ill-conditioned LS system and test */
|
|
Packit |
67cb25 |
test_random(gsl_multilarge_linear_normal, n, p, tol1, r);
|
|
Packit |
67cb25 |
test_random(gsl_multilarge_linear_tsqr, n, p, tol2, r);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_rng_free(r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
exit (gsl_test_summary ());
|
|
Packit |
67cb25 |
}
|