Re: Problems with CLAPACK SVD routines on OS X
- From: "Robert V." <robert.voyer@xxxxxxxxx>
- Date: Thu, 09 Aug 2007 19:12:01 -0000
So I figured out some of these problems yesterday. After much
wrestling with the dgesvd routine, I tried using the dgesdd routine
(the divide-and-conquer svd function) and after I learned that some of
my parameters were invalid, I was able to get some reasonable results.
I'm still not exactly clear on what they should be. The code below
produces the correct singular values but the u and v matrices are not
right. If you have any thoughts given the new code included below, let
me know.
Thanks again,
Robert
#include </System/Library/Frameworks/vecLib.framework/Versions/A/
Headers/clapack.h>
#include <iostream>
#include "f2c.h"
#include <fstream>
#include <string>
#include <sstream>
#include <stdio.h>
#include <algorithm>
using std::cout;
using std::endl;
using std::ifstream;
using std::istringstream;
using std::cerr;
using std::string;
using std::getline;
using std::ios;
using std::max;
using std::min;
int main(int argc, char **argv) {
if (argc < 2) {
cout << "Error. No input file" << endl;
exit(-1);
}
int number = 0;
ifstream infile(argv[1]);
cout << "Opening " << argv[1] << endl;
if (infile.fail()) {
cerr << "unable to open file " << argv[1] << " for reading" <<
endl;
exit(1);
}
// initialize matrix dimension variables
integer M = 0;
integer N = 0;
// pass through infile to determine dimensions
infile.clear();
infile.seekg(0, ios::beg);
string line = "";
while (getline(infile, line)) {
N = 0;
istringstream s(line);
while(s >> number) {
N++;
}
M++;
}
char JOBU;
char JOBVT;
char JOBZ;
integer LDA = N;
integer LDU = N;
integer LDVT = M;
integer INFO = 0;
integer *IWORK = new integer[8*min(M,N)];
doublereal *s = new doublereal[N];
doublereal *wk = new doublereal[3*M*N];
doublereal *uu = new doublereal[M*M];
doublereal *vt = new doublereal[N*N];
// reset file handle
infile.clear();
infile.seekg(0, ios::beg);
cout << "Initializing a " << M << " x " << N << " matrix." << endl;
doublereal *a = new doublereal[M*N];
cout << "Finished initializing..." << endl;
int row = 0;
int column = 0;
int index = 0;
while (getline(infile, line)) {
column = 0;
istringstream s(line);
while(s >> number && (index < (M*N)) && (row < M) && (column < N))
{
if (number > 0) {
//cout << "A[" << row << "][" << column << "] = " << number <<
endl;
a[index] = number;
} else {
a[index] = 0;
}
index++;
column++;
}
row++;
}
infile.close();
JOBU = 'O';
JOBVT = 'A';
JOBZ = 'O';
cout << "Initializing LWORK..." << endl;
//integer LWORK = max(3*min(M,N)+max(M,N),5*min(M,N));
integer SLWORK = (3 * min(M,N) * min(M,N)) + max( max(M,N), 4 *
min(M,N) * min(M,N) + 4 * min(M,N));
/* Subroutine int dgesvd_(char *jobu, char *jobvt, integer *m,
integer *n,
doublereal *a, integer *lda, doublereal *s, doublereal *u,
integer *
ldu, doublereal *vt, integer *ldvt, doublereal *work, integer
*lwork,
integer *info)
*/
cout << "Calculating SVD..." << endl;
//dgesvd_( &JOBU, &JOBVT, &M, &N, a, &LDA, s, uu, &LDU, vt, &LDVT,
wk, &LWORK, &INFO);
dgesdd_(&JOBZ, &N, &M, a, &LDA, s, uu, &LDU, vt, &LDVT, wk, &SLWORK,
IWORK, &INFO);
cout << "\nINFO=" << INFO << endl;
cout << "u =" << endl;
for (int i=0; i<(M*M); i++) {
if (i%(M)==0) {
printf("\n");
}
printf("%.4f ", uu[i]);
}
cout << endl;
for (int i= 0; i< M; i++ ) {
printf("\ns[ %d ] = %.4f", i, s[i]);
}
cout << endl;
cout << "\nvt =" << endl;
for (int i=0; i<(N*N); i++) {
if (i%(N)==0) {
printf("\n");
}
printf("%.4f ", vt[i]);
}
cout << endl;
// delete all of our dynamically allocated objects
delete [] IWORK;
delete [] s;
delete [] wk;
delete [] uu;
delete [] vt;
return 0;
}
OUTPUT
Opening sample.matrix
Initializing a 4 x 5 matrix.
Finished initializing...
Initializing LWORK...
Calculating SVD...
INFO=0
u =
0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
s[ 0 ] = 4.0000
s[ 1 ] = 3.0000
s[ 2 ] = 2.2361
s[ 3 ] = -0.0000
vt =
-0.0000 -0.0000 -1.0000 -0.0000 -0.0000
-1.0000 -0.0000 -0.0000 -0.0000 -0.0000
-0.0000 -1.0000 -1.0000 -0.0000 -0.0000
-0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000 0.0000
Okay, after going over the documentation of dsevd.f
(http://www.netlib.org/lapack/double/dgesvd.f), I have noticed that some
of your parameters are invalid. For example, you are not allocating
proper space for uu and vt. Also, you are allocating the WORK array
prematurely. You should allocate it after defining LWORK and use LWORK
to allocate memory for WORK -- this reduces the changes of error.
Finally, you should be deleting the allocated memory using "delete []
var;" statement since you are allocating arrays. Also, this should be
done just before the return statement in main().
Please fix the above and see if you still get the segmentation fault. We
will then visit the problem of comparison of your results with MATLAB's.
As a side note, you are using functions from LAPACK as well as from BLAS
libraries.
regards,
->HS
.
- Follow-Ups:
- References:
- Problems with CLAPACK SVD routines on OS X
- From: Robert V.
- Re: Problems with CLAPACK SVD routines on OS X
- From: H.S.
- Re: Problems with CLAPACK SVD routines on OS X
- From: mecej4
- Re: Problems with CLAPACK SVD routines on OS X
- From: H.S.
- Re: Problems with CLAPACK SVD routines on OS X
- From: Robert V.
- Re: Problems with CLAPACK SVD routines on OS X
- From: H.S.
- Problems with CLAPACK SVD routines on OS X
- Prev by Date: Re: Problems with CLAPACK SVD routines on OS X
- Next by Date: Re: Problems with CLAPACK SVD routines on OS X
- Previous by thread: Re: Problems with CLAPACK SVD routines on OS X
- Next by thread: Re: Problems with CLAPACK SVD routines on OS X
- Index(es):
Relevant Pages
|