#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <inttypes.h>

#include "libcommon/timestamp.h"
#include "libcommon/units.h"

#include "libmath/gsl_util.h"

int
main (int argc, char *argv[])
{
    gsl_matrix *A = gsl_matrix_alloc (4, 4);
    for (size_t i=0; i<4; i++)
        for (size_t j=0; j<4; j++)
            gsl_matrix_set (A, i, j, ((double)rand ()) / RAND_MAX);
    gslu_matrix_printf (A, "A", NULL);


    double det = gslu_matrix_det (A);
    printf ("\ndet(A)=%g\n", det);

    gsl_matrix *Ainv = gslu_matrix_dup (A);
    gslu_matrix_inv (Ainv);
    gslu_matrix_printf (Ainv, "\nAinv", NULL);
    gsl_matrix_free (Ainv);

    printf ("\nQR factorization of A\n");
    gslu_linalg_QR *qr = gslu_linalg_QR_decomp_alloc (A);
    gsl_matrix *Q = gsl_matrix_alloc (A->size1, A->size1);
    gsl_matrix *R = gsl_matrix_alloc (A->size1, A->size2);
    gsl_linalg_QR_unpack (qr->QR, qr->tau, Q, R);
    gslu_matrix_printf (Q, "Q", NULL);
    gslu_matrix_printf (R, "R", NULL);
    gslu_linalg_QR_free (qr);
    gsl_matrix_free (Q);
    gsl_matrix_free (R);


    printf ("\nSVD decomposition of A\n");
    gslu_linalg_SV *sv = gslu_linalg_SV_decomp_alloc (A);
    gslu_matrix_printf (sv->U, "U", NULL);
    gslu_vector_printf (sv->S, "S", NULL);
    gslu_matrix_printf (sv->V, "V", NULL);
    gslu_linalg_SV_free (sv);

    gsl_matrix_free (A);
}
