00001
00002
00003
00004 #include "Random.hpp"
00005
00006
00007 #include "boost/mpi.hpp"
00008 #include "boost/numeric/bindings/traits/ublas_vector.hpp"
00009 #include "boost/numeric/bindings/traits/ublas_matrix.hpp"
00010 #include "boost/numeric/bindings/lapack/lapack.hpp"
00011
00012 #include <time.h>
00013 #include <assert.h>
00014
00015 using namespace indii::ml::aux;
00016
00017 namespace ublas = boost::numeric::ublas;
00018 namespace lapack = boost::numeric::bindings::lapack;
00019
00020 bool Random::isInit = false;
00021
00022 gsl_rng* Random::rng = NULL;
00023
00024 void Random::seed(unsigned int seed) {
00025 if (!isInit) {
00026 init();
00027 }
00028 gsl_rng_set(rng, seed);
00029 }
00030
00031 void Random::init() {
00032 int seed;
00033
00034
00035 gsl_rng_env_setup();
00036
00037 rng = gsl_rng_alloc(gsl_rng_mt19937);
00038
00039
00040 seed = time(NULL);
00041 if (boost::mpi::environment::initialized()) {
00042
00043 boost::mpi::communicator world;
00044 const int rank = world.rank();
00045 seed += 1000 * rank;
00046 }
00047
00048
00049 gsl_rng_set(rng, seed);
00050 isInit = true;
00051
00052
00053 assert (isInit);
00054 }
00055
00056 void Random::terminate() {
00057 if (isInit) {
00058 gsl_rng_free(rng);
00059 }
00060 }
00061
00062 vector Random::unitVector(const unsigned int N) {
00063 if (!isInit) {
00064 init();
00065 }
00066
00067 aux::vector s(N);
00068 double x[N];
00069 gsl_ran_dir_nd(rng, N, x);
00070 arrayToVector(x, s);
00071
00072 return s;
00073 }
00074
00075 matrix Random::orthonormalMatrix(const unsigned int N) {
00076 if (!isInit) {
00077 init();
00078 }
00079
00080 identity_matrix I(N,N);
00081 matrix random(N,N);
00082 matrix Q(I), H(I);
00083 vector v(N), tau(N);
00084 unsigned int i, j;
00085 int ierr;
00086
00087
00088 for (j = 0; j < N; j++) {
00089 for (i = 0; i < N; i++) {
00090 random(i,j) = Random::uniform(-1.0, 1.0);
00091 }
00092 }
00093
00094
00095
00096
00097
00098
00099 ierr = lapack::geqrf(random, tau);
00100 assert (ierr == 0);
00101
00102
00103
00104 ublas::triangular_adaptor<aux::matrix, ublas::lower> L(random);
00105
00106 for (i = 0; i < N; i++) {
00107 v = column(L,i);
00108 v(i) = 1.0;
00109
00110 H = I - tau(i) * ublas::outer_prod(v,v);
00111 Q = prod(Q,H);
00112 }
00113
00114 return Q;
00115 }
00116