/* nag_complex_svd (f02xec) 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 COMPLEX(A) A.re, A.im
#define COMPLEX_CONJ(A) A.re, -A.im
static int ex1(void), ex2(void);
int main(void)
{
Integer exit_status_ex1 = 0;
Integer exit_status_ex2 = 0;
printf("nag_complex_svd (f02xec) 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 PH(I, J) ph[(I) *tdph + J]
static int ex1(void)
{
Nag_Boolean wantp, wantq;
Complex *a = 0, *b = 0, *dummy = 0, *ph = 0;
Integer exit_status = 0, failinfo, i, iter, j, m, n, ncolb, tda, tdb,
tdph;
NagError fail;
double *e = 0, *sv = 0;
INIT_FAIL(fail);
printf("Example 1\n\n");
scanf(" %*[^\n]"); /* Skip heading in data file */
if (scanf("%ld%ld", &m, &n) != EOF)
{
if (m >= 0 && n >= 0)
{
ncolb = 1;
if (!(e = NAG_ALLOC(MIN(m, n)-1, double)) ||
!(sv = NAG_ALLOC(MIN(m, n), double)) ||
!(a = NAG_ALLOC(m*n, Complex)) ||
!(b = NAG_ALLOC(m*ncolb, Complex)) ||
!(ph = NAG_ALLOC(n*n, Complex)) ||
!(dummy = NAG_ALLOC(1, Complex)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
tda = n;
tdb = ncolb;
tdph = n;
}
else
{
printf("Invalid m or n.\n");
exit_status = 1;
return exit_status;
}
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
scanf("%lf%lf", COMPLEX(&A(i, j)));
for (i = 0; i < m; ++i)
for (j = 0; j < ncolb; ++j)
scanf("%lf%lf", COMPLEX(&B(i, j)));
/* Find the SVD of A. */
wantq = Nag_TRUE;
wantp = Nag_TRUE;
/* nag_complex_svd (f02xec).
* SVD of complex matrix
*/
nag_complex_svd(m, n, a, tda, ncolb, b, tdb, wantq,
dummy, (Integer) 1, sv, wantp, ph, tdph, &iter,
e, &failinfo, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from nag_complex_svd (f02xec).\n%s\n",
fail.message);
exit_status = 1;
goto END;
}
printf("Singular value decomposition of A\n\nSingular values\n");
for (i = 0; i < n; ++i)
printf("%9.4f%s", sv[i], (i%5 == 4 || i == n-1)?"\n":" ");
printf("\nLeft-hand singular vectors, by column\n");
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
printf("%7.4f %7.4f%s", COMPLEX(A(i, j)),
(j%3 == 2 || j == n-1)?"\n":" ");
printf("\nRight-hand singular vectors, by column\n");
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
printf("%7.4f %7.4f%s", COMPLEX_CONJ(PH(j, i)),
(j%3 == 2 || j == n-1)?"\n":" ");
printf("\nVector conjg(Q')*B\n");
for (i = 0; i < m; ++i)
for (j = 0; j < ncolb; ++j)
printf("%7.4f %7.4f%s", COMPLEX(B(i, j)),
(i%3 == 2 || i == m-1)?"\n":" ");
}
END:
NAG_FREE(e);
NAG_FREE(sv);
NAG_FREE(a);
NAG_FREE(b);
NAG_FREE(ph);
NAG_FREE(dummy);
return exit_status;
}
#define A(I, J) a[(I) *tda + J]
#define Q(I, J) q[(I) *tdq + J]
static int ex2(void)
{
Nag_Boolean wantp, wantq;
Complex *a = 0, *dummy = 0, *q = 0;
Integer exit_status = 0, failinfo, i, iter, j, m, n, ncolb, tda, tdq;
NagError fail;
double *e = 0, *sv = 0;
INIT_FAIL(fail);
printf("\nExample 2\n\n");
scanf(" %*[^\n]"); /* Skip heading in data file */
if (scanf("%ld%ld", &m, &n) != EOF)
{
if (m >= 0 && n >= 0)
{
if (!(e = NAG_ALLOC(MIN(m, n)-1, double)) ||
!(sv = NAG_ALLOC(MIN(m, n), double)) ||
!(a = NAG_ALLOC(m*n, Complex)) ||
!(q = NAG_ALLOC(m*m, Complex)) ||
!(dummy = NAG_ALLOC(1, Complex)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
tda = n;
tdq = m;
}
else
{
printf("Invalid m or n.\n");
exit_status = 1;
return exit_status;
}
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
if (scanf("%lf%lf", COMPLEX(&A(i, j))) != 2)
{
printf("Data input error: program terminated.\n");
exit_status = 1;
goto END;
}
/* Find the SVD of A. */
wantq = Nag_TRUE;
wantp = Nag_TRUE;
ncolb = 0;
/* nag_complex_svd (f02xec), see above. */
nag_complex_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_complex_svd (f02xec).\n%s\n",
fail.message);
exit_status = 1;
goto END;
}
printf("Singular value decomposition of A\n\nSingular values\n");
for (i = 0; i < m; ++i)
printf("%9.4f%s", sv[i], (i%5 == 4 || i == m-1)?"\n":" ");
printf("\nLeft-hand singular vectors, by column\n");
for (i = 0; i < m; ++i)
for (j = 0; j < m; ++j)
printf("%7.4f %7.4f%s", COMPLEX(Q(i, j)),
(j%3 == 2 || j == n-1)?"\n":" ");
printf("\nRight-hand singular vectors, by column\n");
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
printf("%7.4f %7.4f%s", COMPLEX_CONJ(A(j, i)),
(j%3 == 2 || j == n-1)?"\n":" ");
}
END:
NAG_FREE(e);
NAG_FREE(sv);
NAG_FREE(a);
NAG_FREE(q);
NAG_FREE(dummy);
return exit_status;
}