/* nag_real_svd (f02wec) Example Program.
*
* Copyright 2014 Numerical Algorithms Group.
*
* Mark 1, 1990.
* Mark 8 revised, 2004.
*/
#include <nag.h>
#include <stdio.h>
#include <nag_stdlib.h>
#include <nagf02.h>
#define EX1_MMAX 20
#define EX1_NMAX 10
static int ex1(void), ex2(void);
int main(void)
{
Integer exit_status_ex1 = 0;
Integer exit_status_ex2 = 0;
printf("nag_real_svd (f02wec) Example Program Results\n");
scanf(" %*[^\n]"); /* Skip heading in data file */
exit_status_ex1 = ex1();
exit_status_ex2 = ex2();
return (exit_status_ex1 == 0 && exit_status_ex2 == 0) ? 0 : 1;
}
#define A(I, J) a[(I) *tda + J]
#define B(I, J) b[(I) *tdb + J]
#define PT(I, J) pt[(I) *tdpt + J]
#define Q(I, J) q[(I) *tdq + J]
static int ex1(void)
{
Nag_Boolean wantp, wantq;
Integer exit_status = 0, failinfo, i, iter, j, m, n, ncolb, tda, tdb,
tdpt;
NagError fail;
double *a = 0, *b = 0, *dummy = 0, *e = 0, *pt = 0, *sv = 0;
INIT_FAIL(fail);
printf("Example 1\n");
scanf(" %*[^\n]"); /* Skip Example 1 heading */
scanf(" %*[^\n]");
scanf("%ld%ld", &m, &n);
if (m >= 0 && n >= 0)
{
ncolb = 1;
if (!(a = NAG_ALLOC(m*n, double)) ||
!(b = NAG_ALLOC(m*ncolb, double)) ||
!(e = NAG_ALLOC(MIN(m, n)-1, double)) ||
!(pt = NAG_ALLOC(n*n, double)) ||
!(sv = NAG_ALLOC(MIN(m, n), double)) ||
!(dummy = NAG_ALLOC(1, double)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
tda = n;
tdb = ncolb;
tdpt = n;
}
else
{
printf("Invalid m or n.\n");
exit_status = 1;
return exit_status;
}
scanf(" %*[^\n]");
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
scanf("%lf", &A(i, j));
scanf(" %*[^\n]");
for (i = 0; i < m; ++i)
for (j = 0; j < ncolb; ++j)
scanf("%lf", &B(i, j));
/* Find the SVD of A. */
wantq = Nag_TRUE;
wantp = Nag_TRUE;
/* nag_real_svd (f02wec).
* SVD of real matrix
*/
nag_real_svd(m, n, a, tda, ncolb, b, tdb, wantq,
dummy, (Integer) 1, sv, wantp, pt, tdpt, &iter,
e, &failinfo, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from nag_real_svd (f02wec).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
printf("Singular value decomposition of A\n\n");
printf("Singular values\n");
for (i = 0; i < n; ++i)
printf(" %8.4f", sv[i]);
printf("\n\n");
printf("Left-hand singular vectors, by column\n");
for (i = 0; i < m; ++i)
{
for (j = 0; j < n; ++j)
printf(" %8.4f", A(i, j));
printf("\n");
}
printf("\n");
printf("Right-hand singular vectors, by column\n");
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
printf(" %8.4f", PT(j, i));
printf("\n");
}
printf("\n");
printf("Vector Q'*B\n");
for (i = 0; i < m; ++i)
printf(" %8.4f", b[i]);
printf("\n\n");
END:
NAG_FREE(a);
NAG_FREE(b);
NAG_FREE(e);
NAG_FREE(pt);
NAG_FREE(sv);
NAG_FREE(dummy);
return exit_status;
}
static int ex2(void)
{
Nag_Boolean wantp, wantq;
Integer exit_status = 0, failinfo, i, iter, j, m, n, ncolb, tda, tdq;
NagError fail;
double *a = 0, *dummy = 0, *e = 0, *q = 0, *sv = 0;
INIT_FAIL(fail);
printf("\nExample 2\n");
scanf(" %*[^\n]"); /* Skip Example 2 heading */
scanf(" %*[^\n]");
scanf("%ld%ld", &m, &n);
if (m >= 0 && n >= 0)
{
if (!(a = NAG_ALLOC(m*n, double)) ||
!(q = NAG_ALLOC(m*m, double)) ||
!(e = NAG_ALLOC(MIN(m, n)-1, double)) ||
!(sv = NAG_ALLOC(MIN(m, n), double)) ||
!(dummy = NAG_ALLOC(1, double)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
}
else
{
printf("Invalid m or n.\n");
exit_status = 1;
return exit_status;
}
tda = n;
tdq = m;
scanf(" %*[^\n]");
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
scanf("%lf", &A(i, j));
/* Find the SVD of A. */
wantq = Nag_TRUE;
wantp = Nag_TRUE;
ncolb = 0;
/* nag_real_svd (f02wec), see above. */
nag_real_svd(m, n, a, tda, ncolb, dummy, (Integer) 1, wantq,
q, tdq, sv, wantp, dummy, (Integer) 1, &iter,
e, &failinfo, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from nag_real_svd (f02wec).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
printf("Singular value decomposition of A\n\n\n");
printf("Singular values\n\n");
for (i = 0; i < m; ++i)
printf(" %8.4f", sv[i]);
printf("\n\n");
printf("Left-hand singular vectors, by column\n\n");
for (i = 0; i < m; ++i)
{
for (j = 0; j < m; ++j)
printf(" %8.4f", Q(i, j));
printf("\n");
}
printf("Right-hand singular vectors, by column\n\n");
for (i = 0; i < n; ++i)
{
for (j = 0; j < m; ++j)
printf(" %8.4f", A(j, i));
printf("\n");
}
END:
NAG_FREE(a);
NAG_FREE(q);
NAG_FREE(e);
NAG_FREE(sv);
NAG_FREE(dummy);
return exit_status;
}