diff --git a/exercises/ex04_skeleton/build_alps.txt b/exercises/ex04_skeleton/build_alps.txt new file mode 100644 index 0000000000000000000000000000000000000000..335b35da23515a052fd0de39c7e8f54c28ad3ab8 --- /dev/null +++ b/exercises/ex04_skeleton/build_alps.txt @@ -0,0 +1,21 @@ +# INSTRUCTIONS +# ============ +# +# 0. Make sure that lapack and blas are available +# (e.g. apt-get install liblapack-dev libblas-dev) +# 1. Download http://alps.comp-phys.org/static/software/releases/alps-2.2.b1-r7195-src-with-boost.tar.gz +# (cf. http://alps.comp-phys.org/mediawiki/index.php/Download_and_install_ALPS_2) +# 2. Unzip it (you do NOT need to build or install anything!) +# 3. Set the following environment variable to the path of the unzipped directory: + +export ALPSDIR=.../alps-2.2.b1-r7195-src-with-boost + +# Now you can compile the skeleton by using: + +c++ -I${ALPSDIR}/boost -I${ALPSDIR}/alps/src -o skeleton skeleton.cpp -llapack -lblas + +# It will fail linking, because you have not yet implemented the Hamiltonian :-) +# +# Happy coding! +# +# If you run into problems that you can't solve, please contact your teaching assistant! diff --git a/exercises/ex04_skeleton/skeleton.cpp b/exercises/ex04_skeleton/skeleton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..324e86c4eab974ca3e2a868a5b21fa1562effeb7 --- /dev/null +++ b/exercises/ex04_skeleton/skeleton.cpp @@ -0,0 +1,59 @@ +#include <vector> +#include <iostream> +#include <fstream> +#include <iomanip> +#include <cassert> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/random.hpp> +#include <boost/tuple/tuple.hpp> + +class Hamiltonian +{ +public: + typedef double Scalar; + typedef boost::numeric::ublas::vector<Scalar> Vector; + + // Dimension of Vector Space + unsigned dimension() const; + + // Calculate y = H x + void multiply(const Vector& x, Vector& y) const; + + // ... +}; + +namespace ietl +{ + /* here we include a "mult" function in the ietl name space specifically designed for use with our Hamiltonian class objects. */ + inline void mult( const Hamiltonian& h, const Hamiltonian::Vector& x, Hamiltonian::Vector& y ) + { + h.multiply( x, y ); + /*To minimize your memory requirements you could implement this method "on the fly", i.e. in a way that never constructs the hamitonian matrix explicitly. */ + } +} + +// ietl::mult() needs to be declared before including these +#include <ietl/interface/ublas.h> +#include <ietl/lanczos.h> + +std::pair< std::vector<double>, std::vector<int> > +diagonalize( const Hamiltonian& h, unsigned nvals=1, unsigned maxiter=1000) +{ + typedef ietl::vectorspace<Hamiltonian::Vector> Vectorspace; + typedef ietl::lanczos<Hamiltonian,Vectorspace> Lanczos; + typedef ietl::lanczos_iteration_nlowest<double> Iteration; + typedef boost::mt19937 Generator; + + Vectorspace vspace(h.dimension()); + Lanczos solver(h,vspace); + Iteration iter(maxiter,nvals); /* maxiter limits the number of Lanczos iterations and nvals tells the solver the number of eigenvalues to calculate.*/ + solver.calculate_eigenvalues(iter,Generator()); /* Generator() creates a pseudo-random number generator (Mersenne-Twister) used for starting the Lanczos algorithm. */ + + if( iter.iterations() == maxiter ) + std::cerr << "Lanczos did not converge in " << iter.iterations() << " iterations." << std::endl; + else + std::cout << " Lanczos converged after " << iter.iterations() << " iterations." << std::endl; + + return std::make_pair(solver.eigenvalues(),solver.multiplicities()); +} + diff --git a/exercises/ex04_skeleton/skeleton.py b/exercises/ex04_skeleton/skeleton.py new file mode 100644 index 0000000000000000000000000000000000000000..c477c33edd92f30ec7e2c204c440304d324b9991 --- /dev/null +++ b/exercises/ex04_skeleton/skeleton.py @@ -0,0 +1,21 @@ +import math as m, numpy as np + +from scipy.sparse.linalg as la +# Documentation at http://docs.scipy.org/doc/scipy/reference/sparse.linalg.html + +d = # size of local basis +L = # length of the chain + + +def heisenberg(v): +""" +Given an input vector v, this function returns H*v. +""" + pass + +def sparse_diag(): + D = d**L + H = la.LinearOperator( (D,D), matvec=heisenberg, dtype='D') + (w,v) = la.eigsh(H, 10, which='SA') + return w + diff --git a/exercises/exercise4.pdf b/exercises/exercise4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9a3757a71b885eeac1d7cfd00043a6612eeda9c8 Binary files /dev/null and b/exercises/exercise4.pdf differ