Vous êtes sur la page 1sur 4

Examen - Instalacin de libreras y Errores Numricos en la Computacin

William Oquendo, woquendo@gmail.com

Contents
1 (2.5/5.0) Oscilador anarmnico cuntico 1

2 (1.0/5.0) Bono: Oscilador Anarmnico - Energa del estado base en funcin de 3

3 (2.5/5.0) Matriz de Hilbert 3

Abstract
Solamente se recibe y califica lo enviado a travs de github. Debe estar presente en el saln al realizar la prueba.
Siga las instrucciones de nombres que especifica cada ejercicio. Por defecto, para cada ejercicio cree un archivo con el
numero de ejercicio y la extensin apropiada. Por ejemplo, si en el problema 1 le piden hacer un programa, entonces
la solucin sera un archivo llamado 1.cpp . Pero si en el ejercicio 5 le piden responder o hacer un anlisis, entonces
la solucin se escribira en un archivo 5.txt . Cada archivo de respuesta debe estar incluido en el repositorio pero en
commits diferentes. Se evaluar lo enviado al repositorio remoto asignado hasta la hora de finalizacin del examen.
A menos que se indique lo contrario, ningn programa deber pedir entrada de usuario. Haga uso de lo visto hasta
ahora en el curso, adems de lo que se pide explcitamente en cada punto. Todos los cdigos que usted enve sern
chequeados con los sanitizers y con valgrind y no deben presentar errores.

1 (2.5/5.0) Oscilador anarmnico cuntico


El objetivo de este problema es encontrar los valores lmite de la energa del estado base y del primer estado excitado como
funciones del tamao del sistema para un oscilador armnico cuntico anarmnico. Para esto se usar la representacin
matricial del hamiltoniano y su usar la librera eigen para resolver el problema de valores propios como funcin del
tamao del sistema y de la intensidad de la perturbacin.
Un oscilador anarmnico cuntico puede modelarse como una perturbacin al oscilador armnico cuntico de la forma

H() = H0 + x4 , (1)

donde H denota el hamiltoniano y es un nmero pequeo que modela la perturbacin al hamiltoniano original H0 .
Si se desea encontrar los valores propios perturbados, se debe resolver la ecuacin H()|ni = En |ni. En la repre-
sentacin matricial, se obtiene que
 
1
H0,nm = n + n,m , (2)
2
1 1
xnm = m + 1 n,m+1 + m n,m1 , (3)
2 2
Hnm () = H0,nm + (x4 )nm , (4)

donde es el delta de Kronecker (1 si n = m, 0 en cualquier otro caso), x4 = x x x x, y los valores propios


dependen del tamao de la matriz y de , En = En (N, ). Los valores propios de la matriz Hnm () representan las
energas de los estados propios del sistema. El menor valor corresponde al estado base y est dado por E0 (N, ). En
este punto, usted explorar cmo depende E0 (N, ) con N , para = 0.2 fijo.
Cree un programa que calcule los valores propios del hamiltoniano perturbado, le permita extraer el de menor valor,
y al final imprima el valor de ese valor propio en funcin del inverso del tamao del sistema, 1/N , para = 0.2. Tome
N = 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024. La salida debe ser algo como

1
5.0000000000000000e-01 5.5000000000000004e-01
2.5000000000000000e-01 5.9470546427531512e-01
1.2500000000000000e-01 6.0248643158149484e-01
.. ..
. .
9.7656250000000000e-04 6.0240516362982810e-01
Guarde el programa en el archivo 1.cpp .
Use como plantilla el cdigo que sigue:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <eigen3/Eigen/Dense>
#include <eigen3/Eigen/EigenValues>

void set_H0(Eigen::MatrixXd & M);


void set_X(Eigen::MatrixXd & M);
double eigen_energy(Eigen::MatrixXd & H, Eigen::MatrixXd & X, const double lambda, const int index);

int main(int argc, char **argv)


{
std::cout.precision(16);
std::cout.setf(std::ios::scientific);

double lambda = 0.2;


for (int N = 2; N <= 1024; N *= 2) {
Eigen::MatrixXd X(N, N), H0(N, N);
set_H0(H0);
set_X(X);
std::cout << 1.0/N << " " << eigen_energy(H0, X, lambda, 0) << std::endl;
}

return 0;
}

void set_H0(Eigen::MatrixXd & M)


{
M.setZero();
// Escriba aca el codigo que crea la matriz H0
// Puede guiarse por la funcion set_X
}

void set_X(Eigen::MatrixXd & M)


{
M.setZero();
for (int n = 0; n < M.cols(); ++n){
for (int m = 0; m < M.cols(); ++m){
if (n == m+1) M(n, m) += std::sqrt((m+1.0)/2.0);
if (n == m-1) M(n, m) += std::sqrt((m)/2.0);
}
}
}

double eigen_energy(Eigen::MatrixXd & H, Eigen::MatrixXd & X, const double lambda, const int index)
{
// Implemente aca el calculo de los valores propios, usando la libreria eigen

// - Calculo de Hlambda :

// - Calculo de los valores propios (y vectores propios) :

2
// - Extraer los valores propios al vector Eigen::VectorXd evals, solamente
// la parte real (cuando pida los valores propios escriba .eigenvalues.real()) :

// ordenar los valores propios :


std::sort(evals.data(), evals.data() + evals.size());
// retornar el valor propio (para el estado base index == 0) :
return evals(index);
}

Como puede ver, este programa tambin le es til para calcular la energa de estados exitados cuando el ndice es diferente
a cero.

2 (1.0/5.0) Bono: Oscilador Anarmnico - Energa del estado base en


funcin de
En este punto de bono usted usar el programa del punto anterior y ahora variar = 0.0, 0.1, 0.2, 0.3, . . . , 1.0, con
N = 1024 fijo, e imprimir E0 (1024, ) como funcin de . Llame a su programa 2.cpp. Su programa debe imprimir
algo como
0.0000000000000000e+00 5.0000000000000000e-01
1.0000000000000001e-01 5.5914632714660617e-01
2.0000000000000001e-01 6.0240516362982810e-01
.. ..
. .
9.9999999999999989e-01 8.0377065051388363e-01
Como puede ver, la energa del estado base crece con el valor de la perturbacin de una forma casi de ley de potencias.

3 (2.5/5.0) Matriz de Hilbert


Una matriz de Hilbert se define como  
1
A = [aij ] = , (5)
i+j+1
en donde los ndices varan entre 0 y N 1). La matriz de Hilbert es una matriz mal condicionada, es decir, presenta
mucha inestabilidad numrica al resolver el sistema A~x = ~b. La inestabilidad se puede medir usando el llamado condition
number, definido como
(A) = ||A|| ||A1 ||, (6)
es decir, es igual a la multiplicacin de la norma de la matriz y la norma de la matriz inversa. Si es mayor que uno, la
matriz es ill-conditioned y cualquier perturbacin ser amplificada.
Calcule como funcin del tamao N de la matriz para N = 12, 4, 8, 16, 32, . . . , 4096. Guarde el cdigo en el
archivo 3.cpp. Su programa debe imprimir algo como
1 1.0000000000000000e+00
2 1.9333333333333336e+01
4 1.5613793559642372e+04
.. ..
. .
4096 1.4883648044520246e+21
Utilice como base el siguiente cdigo

#include <iostream>
#include <cmath>
#include <eigen3/Eigen/Dense>

void set_as_hilbert(Eigen::MatrixXd & M);


double condition_number(Eigen::MatrixXd & M);

3
int main(int argc, char **argv)
{
std::cout.precision(16);
std::cout.setf(std::ios::scientific);

for (int N = 1; N <= 4096; N *= 2) {


Eigen::MatrixXd M(N, N);
set_as_hilbert(M);
std::cout << N << " " << condition_number(M) << std::endl;
}
return 0;
}

void set_as_hilbert(Eigen::MatrixXd & M)


{
M.setZero();
// Escriba el codigo para iniciar esta matriz como matriz de Hilbert

double condition_number(Eigen::MatrixXd & M)


{
// Escriba aca el codigo para calcular el condition number. Puede
// ser una sola linea! Se le recomienda buscar como calcular la
// norma de una matriz de eigen (funcion .norm() ?)

Vous aimerez peut-être aussi