├── extra ├── qdpack-logo.png ├── qdpack-square-logo.png ├── qdpack-logo-v1.svg ├── qdpack-square-logo-v2.svg └── qdpack-square-logo-v1.svg ├── README.md ├── .gitignore ├── batch ├── sge_submit_wrapper.sh ├── ubuntu_submit.sh ├── sge_submit.sh ├── mosix_submit.sh └── batchspec.py ├── qdpack ├── qdpack_matrix.c ├── gsl_ext_rscc.h ├── qdpack_matrix.h ├── gsl_ext_expm_complex.h ├── entanglement.h ├── floquet.h ├── basis_transform.h ├── steadystate_sparse.h ├── Makefile ├── steadystate.h ├── gsl_ext.h ├── qdpack.h ├── states.h ├── simulation.c ├── composite.h ├── hilbert_space.h ├── io.h ├── mlib.h ├── gsl_ext_sparse.h ├── master_equation.h ├── operators.h ├── distribution_functions.h ├── integrate.h ├── gsl_ext_rscc.c ├── qdpack_object.h ├── simulation.h ├── basis_transform.c ├── qdpack_matrix_gsl.h ├── qdpack_matrix_cxsparse.h ├── hilbert_space.c ├── hamiltonian.h ├── gsl_ext_expm_complex.c ├── entanglement.c └── gsl_ext.c ├── examples ├── Makefile ├── run_jc.c ├── run_nTLS.c ├── run_2ls_driven_pss.c ├── run_spinchain.c ├── run_qubits.c ├── run_adiabatic.c └── run_qubit_tls.c ├── tests ├── test-complex.c ├── state_test.c ├── operator_test.c ├── operator_test_2.c ├── Makefile ├── test_basis_transform.c ├── test_operator_J.c ├── test_operator_3ls.c ├── dm_test.c ├── test_sparse_matrix.c ├── expm_test.c ├── test_matrix_backend.c ├── test_matrix_backend_gsl.c ├── test_matrix_backend_cxsparse_conversion.c ├── test_matrix_fops.c ├── eigen_cmpl_test.c └── test_matrix_backend_cxsparse.c ├── Makefile └── install-ubuntu.txt /extra/qdpack-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrjohansson/qdpack/master/extra/qdpack-logo.png -------------------------------------------------------------------------------- /extra/qdpack-square-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jrjohansson/qdpack/master/extra/qdpack-square-logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | qdpack 2 | ====== 3 | 4 | Quantum Dynamics package. A numerical package for simulation of quantum system (unitary evolution, dissipative evolution, steady state, expectation values and correlation functions, etc). 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | -------------------------------------------------------------------------------- /batch/sge_submit_wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # setup the execution environment 4 | #TARGETBIN=$2-`date +%s` 5 | #TARGETBIN=$2-`date +%F-%T` 6 | TARGETBIN=$2-`date +%F-%H-%M-%S` 7 | echo "Starting batch jobs for the binary " $TARGETBIN 8 | cp $2 $TARGETBIN 9 | mkdir /home/rob/qdpack-data/$TARGETBIN 10 | 11 | qsub batch/qdp_sge.sh $1 $TARGETBIN 12 | -------------------------------------------------------------------------------- /batch/ubuntu_submit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # time sh batch/ubuntu_submit.sh batch/batchspec.py run_qubits 1 5 | # 6 | 7 | # setup the execution environment 8 | TARGETBIN=$2-`date +%F-%H-%M-%S` 9 | echo "Starting batch jobs for the binary " $TARGETBIN 10 | cp $2 $TARGETBIN 11 | mkdir /home/rob/qdpack-data/$TARGETBIN 12 | 13 | 14 | #!/bin/sh 15 | 16 | N=$3 17 | 18 | 19 | for i in `seq 1 $N`; 20 | do 21 | python $1 $N $i 1 $TARGETBIN & 22 | 23 | sleep 1 24 | done 25 | 26 | wait 27 | -------------------------------------------------------------------------------- /batch/sge_submit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # SGE configuration: 4 | #$ -cwd 5 | #$ -o output/stdout-1.log 6 | #$ -e output/stderr-1.log 7 | #$ -t 1-100 8 | 9 | # Setup scientific python environment 10 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/beowulf/lib/atlas:/beowulf/lib/ 11 | export PYTHONPATH=/beowulf/python-modules 12 | export MATPLOTLIBDATA=/beowulf/python-modules/matplotlib/ 13 | 14 | # setup the execution environment 15 | 16 | # Execute the wrapper script 17 | python $1 100 $SGE_TASK_ID $$ $2 18 | -------------------------------------------------------------------------------- /batch/mosix_submit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # setup the execution environment 4 | #TARGETBIN=$2-`date +%s` 5 | #TARGETBIN=$2-`date +%F-%T` 6 | TARGETBIN=$2-`date +%F-%H-%M-%S` 7 | echo "Starting batch jobs for the binary " $TARGETBIN 8 | cp $2 $TARGETBIN 9 | mkdir /home/rob/qdpack-data/$TARGETBIN 10 | 11 | 12 | #!/bin/sh 13 | 14 | N=$3 15 | 16 | 17 | for i in `seq 1 $N`; 18 | do 19 | run python $1 $N $i 1 $TARGETBIN & 20 | #python $1 25 $SGE_TASK_ID $$ $2 21 | 22 | sleep 5 23 | done 24 | 25 | wait 26 | -------------------------------------------------------------------------------- /qdpack/qdpack_matrix.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | #include 10 | 11 | // select matrix backend 12 | #ifdef USE_DENSE 13 | #include "qdpack_matrix_gsl.c" 14 | #endif 15 | 16 | #ifdef USE_SPARSE 17 | #include "qdpack_matrix_cxsparse.c" 18 | #endif 19 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Copyright (C) 2012, Robert Johansson 3 | # All rights reserved. 4 | # 5 | # This file is part of QDpack, and licensed under the LGPL. 6 | # http://dml.riken.jp/~rob/qdpack.html 7 | #------------------------------------------------------------------------------- 8 | 9 | PROGRAMS=run_qubits run_jc run_spinchain run_2ls_driven_pss 10 | 11 | all: 12 | for i in ${PROGRAMS}; do \ 13 | echo Building $$i; \ 14 | $(CC) -o $$i $$i.c -I.. $(CFLAGS) ../qdpack/libqdpack.a $(LDFLAGS) ; \ 15 | done 16 | 17 | install: 18 | echo "nothing..." 19 | 20 | clean: 21 | rm -rf *.o *~ $(PROGRAMS) 22 | -------------------------------------------------------------------------------- /qdpack/gsl_ext_rscc.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | 10 | int gsl_matrix_complex_add_diagonal (gsl_matrix_complex * a, const gsl_complex x); 11 | int gsl_matrix_complex_scale (gsl_matrix_complex * a, const gsl_complex x); 12 | int gsl_matrix_complex_add (gsl_matrix_complex * a, const gsl_matrix_complex * b); 13 | int gsl_matrix_complex_sub (gsl_matrix_complex * a, const gsl_matrix_complex * b); 14 | 15 | -------------------------------------------------------------------------------- /qdpack/qdpack_matrix.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // select matrix backend 10 | #include 11 | 12 | #ifndef USE_DENSE 13 | #ifndef USE_SPARSE 14 | #error Must compile with USE_DENSE or USE_SPARSE 15 | #endif 16 | #endif 17 | 18 | #ifdef USE_DENSE 19 | #include 20 | #endif 21 | 22 | #ifdef USE_SPARSE 23 | #include 24 | #endif 25 | -------------------------------------------------------------------------------- /qdpack/gsl_ext_expm_complex.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Implementation of matrix-exponentiation for complex matrices. 11 | */ 12 | 13 | #ifndef GSL_EXPM_COMPLEX_H 14 | #define GSL_EXPM_COMPLEX_H 15 | 16 | #include 17 | #include 18 | 19 | int gsl_linalg_complex_exponential_ss(const gsl_matrix_complex *A, gsl_matrix_complex *eA, gsl_mode_t mode); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /tests/test-complex.c: -------------------------------------------------------------------------------- 1 | // 2 | // Test complex number abstraction 3 | // 4 | // 5 | 6 | #include 7 | #include "qdpack_matrix_cxsparse.h" 8 | 9 | int 10 | main(int argc, char *argv) 11 | { 12 | qdpack_complex z1, z2, z3; 13 | 14 | QDPACK_SET_COMPLEX(&z1, 1.3, 0.3); 15 | z2 = qdpack_complex_rect(4.3, 1.2); 16 | 17 | printf("z1 = %.3f + %.3fi\n", QDPACK_REAL(z1), QDPACK_IMAG(z1)); 18 | printf("z2 = %.3f + %.3fi\n", QDPACK_REAL(z2), QDPACK_IMAG(z2)); 19 | 20 | z3 = qdpack_complex_add(z1, z2); 21 | 22 | printf("z1+z2 = %.3f + %.3fi\n", QDPACK_REAL(z3), QDPACK_IMAG(z3)); 23 | 24 | z3 = qdpack_complex_sub(z1, z2); 25 | 26 | printf("z1-z2 = %.3f + %.3fi\n", QDPACK_REAL(z3), QDPACK_IMAG(z3)); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /tests/state_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | #include "quantum_system.h" 8 | #include 9 | 10 | int 11 | main(int argc, char **argv) 12 | { 13 | quantum_system *qs; 14 | quantum_system_state_vector_t qsv; 15 | int qsn, i; 16 | 17 | qs = quantum_system_new(); 18 | 19 | quantum_system_print(qs); 20 | 21 | quantum_system_add(qs, 5); 22 | quantum_system_add(qs, 5); 23 | 24 | quantum_system_print(qs); 25 | 26 | 27 | qsn = quantum_system_nstates(qs); 28 | 29 | for (i = 0; i < qsn; i++) 30 | { 31 | quantum_system_state_vector(qs, i, qsv); 32 | 33 | printf("qsn = %d\t->\t", i); 34 | quantum_system_state_vector_print(qs, qsv); 35 | printf("\t->\tqsn = %d\n", quantum_system_state_number(qs, qsv)); 36 | 37 | } 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /qdpack/entanglement.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for calculating quantifying entanglement. 11 | */ 12 | 13 | #ifndef ENTANGLEMENT_H 14 | #define ENTANGLEMENT_H 15 | 16 | #include 17 | 18 | #include "qdpack.h" 19 | 20 | double qdpack_entanglement_concurrence(qdpack_hilbert_space_t *qs, qdpack_operator_t *rho); 21 | double qdpack_entanglement_log_neg(qdpack_operator_t *rho); 22 | double qdpack_entanglement_neumann_entropy(qdpack_operator_t *rho); 23 | 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /qdpack/floquet.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for calculating floquet modes and evolution. 11 | */ 12 | 13 | #ifndef MASTER_EQUATION_H 14 | #define MASTER_EQUATION_H 15 | 16 | #include 17 | 18 | int qdpack_floquet_modes(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs); 19 | int qdpack_floquet_modes_t(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, double t); 20 | int qdpack_floquet_dissipation_rates(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, operator_cb_func_t floquet_state_store_cb, spectral_density_cb_t s_func); 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /qdpack/basis_transform.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for calculating basis transformation matrices, etc. 11 | * 12 | */ 13 | 14 | #ifndef BASIS_TRANSFORM_H 15 | #define BASIS_TRANSFORM_H 16 | 17 | #include "hilbert_space.h" 18 | #include "simulation.h" 19 | 20 | //typedef double (*ho_w_func_t)(double t, qdpack_simulation_t *sp); 21 | 22 | qdpack_operator_t *basis_transform(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, int n, ho_w_func_t ho_w_cb, double t); 23 | qdpack_operator_t *basis_transform_derivative(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, int n, ho_w_func_t ho_w_cb, double t); 24 | 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /qdpack/steadystate_sparse.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for calculating the steady state of a system with dissipation. 11 | * Using sparse matrix algebra. 12 | */ 13 | 14 | #ifndef STEADY_STATE_SPARSE_H 15 | #define STEADY_STATE_SPARSE_H 16 | 17 | #include 18 | 19 | #include "hilbert_space.h" 20 | #include "simulation.h" 21 | 22 | int qdpack_steadystate_dm_sparse(qdpack_hilbert_space_t *qs, qdpack_operator_t *rho_ss, qdpack_simulation_t *param); 23 | int qdpack_steadystate_dm_propagator(qdpack_hilbert_space_t *qs, qdpack_simulation_t *param, qdpack_operator_t *rho_ss, qdpack_operator_t *U); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /qdpack/Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Copyright (C) 2012, J Robert Johansson 3 | # All rights reserved. 4 | # 5 | # This file is part of QDpack, and licensed under the LGPL. 6 | # http://dml.riken.jp/~rob/qdpack.html 7 | #------------------------------------------------------------------------------- 8 | 9 | QDLIB=mlib.o integrate.o entanglement.o hamiltonian.o hilbert_space.o states.o \ 10 | composite.o operators.o master_equation.o basis_transform.o steadystate.o \ 11 | distribution_functions.o qdpack_object.o simulation.o io.o floquet.o \ 12 | qdpack_matrix.o gsl_ext_expm_complex.o gsl_ext_expm_complex.o gsl_ext.o 13 | 14 | #gsl_ext_sparse.o steady_sparse.o 15 | 16 | lib: $(QDLIB) 17 | ar $(ARFLAGS) libqdpack.a $(QDLIB) 18 | 19 | install: lib 20 | cp libqdpack.a /usr/local/lib/libqdpack.a 21 | mkdir -p /usr/local/include/qdpack 22 | cp *.h /usr/local/include/qdpack/ 23 | 24 | clean: 25 | rm -rf *.o *~ libqdpack.a 26 | -------------------------------------------------------------------------------- /qdpack/steadystate.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for calculating the steady state of a system with dissipation. 11 | */ 12 | 13 | #ifndef STEADY_STATE_H 14 | #define STEADY_STATE_H 15 | 16 | #include 17 | 18 | #include "hilbert_space.h" 19 | #include "simulation.h" 20 | 21 | int qdpack_steadystate_dm(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho_ss); 22 | int qdpack_steadystate_dm_eig(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho_ss); 23 | int qdpack_steadystate_dm_propagator(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *U, qdpack_operator_t *rho_ss); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /tests/operator_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | #include "quantum_system.h" 8 | #include "operators.h" 9 | #include "misc.h" 10 | 11 | #include 12 | #include 13 | 14 | 15 | int 16 | main(int argc, char **argv) 17 | { 18 | gsl_matrix_complex *sx1, *sx2, *sz1, *sz2; 19 | quantum_system *qs; 20 | quantum_system_state_vector_t qsv; 21 | int qsn, i; 22 | 23 | qs = quantum_system_new(); 24 | 25 | quantum_system_print(qs); 26 | quantum_system_add(qs, 2); 27 | //quantum_system_add(qs, 4); 28 | quantum_system_print(qs); 29 | 30 | qsn = quantum_system_nstates(qs); 31 | 32 | 33 | sx1 = operator_sigma_x(qs, 0); 34 | printf("sx1 =\n"); 35 | misc_matrix_complex_print(sx1, qsn); 36 | 37 | sz1 = operator_sigma_z(qs, 0); 38 | printf("sz1 =\n"); 39 | misc_matrix_complex_print(sz1, qsn); 40 | 41 | sx2 = operator_ho_raising(qs, 1); 42 | printf("sx2 =\n"); 43 | misc_matrix_complex_print(sx2, qsn); 44 | 45 | sz2 = operator_ho_lowering(qs, 1); 46 | printf("sz1 =\n"); 47 | misc_matrix_complex_print(sz2, qsn); 48 | 49 | 50 | 51 | 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /tests/operator_test_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | #include "quantum_system.h" 8 | #include "operators.h" 9 | #include "misc.h" 10 | 11 | #include 12 | #include 13 | 14 | 15 | int 16 | main(int argc, char **argv) 17 | { 18 | gsl_matrix_complex *sx1, *sx2, *sz1, *sz2; 19 | quantum_system *qs; 20 | quantum_system_state_vector_t qsv; 21 | int qsn, i; 22 | 23 | qs = quantum_system_new(); 24 | 25 | quantum_system_print(qs); 26 | quantum_system_add(qs, 5); 27 | //quantum_system_add(qs, 2); 28 | quantum_system_print(qs); 29 | 30 | qsn = quantum_system_nstates(qs); 31 | 32 | /* 33 | 34 | sx1 = operator_sigma_x(qs, 1); 35 | printf("sx1 =\n"); 36 | misc_matrix_complex_print(sx1, qsn); 37 | 38 | sz1 = operator_sigma_z(qs 1,; 39 | printf("sz1 =\n"); 40 | misc_matrix_complex_print(sz1, qsn); 41 | */ 42 | 43 | 44 | sx2 = operator_ho_raising(qs, 0, 2); 45 | printf("a* =\n"); 46 | misc_matrix_complex_print(sx2, qsn); 47 | 48 | sz2 = operator_ho_lowering(qs, 0, 2); 49 | printf("a =\n"); 50 | misc_matrix_complex_print(sz2, qsn); 51 | 52 | 53 | 54 | 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Copyright (C) 2012, Robert Johansson 3 | # All rights reserved. 4 | # 5 | # This file is part of QDpack, and licensed under the LGPL. 6 | # http://dml.riken.jp/~rob/qdpack.html 7 | #------------------------------------------------------------------------------- 8 | 9 | PROGRAMS=test_matrix_fops test_matrix_backend 10 | 11 | all: 12 | for i in ${PROGRAMS}; do \ 13 | echo Building $$i; \ 14 | $(CC) -o $$i $$i.c -I.. $(CFLAGS) ../qdpack/libqdpack.a $(LDFLAGS) ; \ 15 | done 16 | $(CC) -o test_matrix_backend_gsl test_matrix_backend_gsl.c ../qdpack/qdpack_matrix_gsl.c ../qdpack/gsl_ext_expm_complex.c ../qdpack/gsl_ext.c -I.. $(CFLAGS) $(LDFLAGS) 17 | $(CC) -o test_matrix_backend_cxsparse test_matrix_backend_cxsparse.c ../qdpack/qdpack_matrix_cxsparse.c -I.. $(CFLAGS) $(LDFLAGS) 18 | $(CC) -o test_matrix_backend_cxsparse_conversion test_matrix_backend_cxsparse_conversion.c ../qdpack/qdpack_matrix_cxsparse.c -I.. $(CFLAGS) $(LDFLAGS) 19 | 20 | install: 21 | echo "nothing..." 22 | 23 | clean: 24 | rm -rf *.o *~ $(PROGRAMS) 25 | 26 | -------------------------------------------------------------------------------- /batch/batchspec.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from Numeric import * 3 | import sys 4 | import os 5 | 6 | #spx = arange(0.1, 20, 0.1) 7 | spx = arange(0.75, 1.25, 0.005) 8 | spx = arange(0.7, 1.31, 0.01) 9 | spx = arange(8.6, 9.2 + 0.005, 0.005) 10 | 11 | N = int(sys.argv[1]) 12 | n = int(sys.argv[2]) 13 | pid = int(sys.argv[3]) 14 | progname = sys.argv[4].lstrip().rstrip() 15 | 16 | print "Running batch", n, "out of", N, "using binary :" + progname + ":" 17 | 18 | prog = "time ./" + progname 19 | preargs = " " 20 | postargs = " 0.75 0.005 1.25" 21 | postargs = " 11.585 0.0001 11.605" 22 | 23 | # split sp array in N pieces. 24 | def split_array(spx, N): 25 | sa = [] 26 | for i in range(0, N): 27 | a = [] 28 | sa.append(a) 29 | k = 0 30 | for i in range(0, len(spx)): 31 | sa[k].append(spx[i]) 32 | k = int((k+1)%N) 33 | return sa 34 | 35 | # execute run 36 | sa = split_array(spx, N) 37 | 38 | for p1 in sa[int(n-1)]: 39 | print "Running", p1, "from", sa[int(n-1)] 40 | exec_str = str(prog)+str(preargs)+str(p1)+str(postargs) 41 | print "Executing: ", exec_str 42 | os.system(exec_str) 43 | #os.system(str(prog)+str(preargs)+str(p1)+" "+str(p2)+" "+str(postargs)) 44 | -------------------------------------------------------------------------------- /tests/test_basis_transform.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test basis transform matrix generation. 3 | * 4 | * J Robert Johansson, 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | #define wm 1.00 14 | #define wp 0.85 15 | #define g 1.0 16 | #define T 10.0 17 | 18 | static double 19 | ho_w_func(double t, void *data) 20 | { 21 | double w = sqrt(wm*wm + (wp*wp-wm*wm) / (1 + exp(-2.0 * g * (t-T)))); 22 | 23 | printf("DEBUG: ho_w: w(t=%f) = %f\n", t, w); 24 | 25 | return w; 26 | } 27 | 28 | int 29 | main(int argc, char **argv) 30 | { 31 | gsl_matrix_complex *S, *dS; 32 | quantum_system *qs; 33 | int qsn, i; 34 | 35 | qs = quantum_system_new(); 36 | quantum_system_print(qs); 37 | quantum_system_add(qs, 10); 38 | // quantum_system_add(qs, 5); 39 | quantum_system_print(qs); 40 | qsn = quantum_system_nstates(qs); 41 | 42 | S = basis_transform(qs, 0, (ho_w_func_t)ho_w_func, 8.5); 43 | printf("S =\n"); 44 | misc_matrix_complex_print_real(S, qsn); 45 | dS = basis_transform_derivative(qs, 0, (ho_w_func_t)ho_w_func, 8.5); 46 | printf("dS =\n"); 47 | misc_matrix_complex_print_real(dS, qsn); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tests/test_operator_J.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test the angular momentum operators: 3 | * 4 | */ 5 | #include "quantum_system.h" 6 | #include "operators.h" 7 | #include "misc.h" 8 | 9 | #include 10 | #include 11 | 12 | 13 | int 14 | main(int argc, char **argv) 15 | { 16 | gsl_matrix_complex *Jz, *Jp, *Jm; 17 | quantum_system *qs; 18 | quantum_system_state_vector_t qsv; 19 | int qsn, n, N = 3; 20 | double j, jmax = 5.0/2.0; 21 | 22 | for (j = 0; j <= jmax; j += 0.5) 23 | { 24 | qs = quantum_system_new(); 25 | quantum_system_add(qs, 2 * j + 1); 26 | quantum_system_print(qs); 27 | 28 | qsn = quantum_system_nstates(qs); 29 | 30 | printf("======================================================================\n"); 31 | printf("=== Calculating angular momentum operators for a spin = %.3f particle\n", j); 32 | 33 | Jz = operator_Jz(qs, 0, j); 34 | printf("Jz =\n"); 35 | misc_matrix_complex_print_real(Jz, qsn); 36 | 37 | Jp = operator_J_plus(qs, 0, j); 38 | printf("Jp =\n"); 39 | misc_matrix_complex_print_real(Jp, qsn); 40 | 41 | Jm = operator_J_minus(qs, 0, j); 42 | printf("Jm =\n"); 43 | misc_matrix_complex_print_real(Jm, qsn); 44 | 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /tests/test_operator_3ls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | #include "quantum_system.h" 8 | #include "operators.h" 9 | #include "misc.h" 10 | 11 | #include 12 | #include 13 | 14 | 15 | int 16 | main(int argc, char **argv) 17 | { 18 | gsl_matrix_complex *sx1, *sx2, *sz1, *sz2; 19 | quantum_system *qs; 20 | quantum_system_state_vector_t qsv; 21 | int qsn, i; 22 | 23 | qs = quantum_system_new(); 24 | 25 | quantum_system_add(qs, 3); 26 | quantum_system_print(qs); 27 | 28 | qsn = quantum_system_nstates(qs); 29 | 30 | sx1 = operator_3ls_sigma_x(qs, 0); 31 | printf("sx1 =\n"); 32 | misc_matrix_complex_print(sx1, qsn); 33 | 34 | sz1 = operator_3ls_sigma_z(qs, 0); 35 | printf("sz1 =\n"); 36 | misc_matrix_complex_print(sz1, qsn); 37 | 38 | sx2 = operator_project(qs, 0, 0, 2); 39 | printf("proj =\n"); 40 | misc_matrix_complex_print(sx2, qsn); 41 | sx2 = operator_project(qs, 0, 2, 0); 42 | printf("proj' =\n"); 43 | misc_matrix_complex_print(sx2, qsn); 44 | 45 | sx2 = operator_project(qs, 0, 2, 1); 46 | printf("proj =\n"); 47 | misc_matrix_complex_print(sx2, qsn); 48 | sx2 = operator_project(qs, 0, 1, 2); 49 | printf("proj' =\n"); 50 | misc_matrix_complex_print(sx2, qsn); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /qdpack/gsl_ext.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * A collection of functions that extend the GSL. 11 | */ 12 | 13 | #ifndef GSL_EXT_H 14 | #define GSL_EXT_H 15 | 16 | #include 17 | #include 18 | 19 | #ifdef RCSS 20 | #include "gsl_ext_rscc.h" 21 | #endif 22 | 23 | int gsl_ext_matrix_convert(gsl_matrix_complex *dst, gsl_matrix *src); 24 | gsl_matrix_complex *gsl_ext_matrix_convert_and_free(gsl_matrix *m); 25 | 26 | int gsl_ext_expm_complex(gsl_matrix_complex *A, gsl_matrix_complex *eA); 27 | 28 | int gsl_ext_eigen_zgeev(gsl_matrix_complex *A_gsl, gsl_matrix_complex *evec, gsl_vector_complex *eval); 29 | 30 | #define GSL_EXT_EIGEN_SORT_ABS 0 31 | #define GSL_EXT_EIGEN_SORT_REAL 1 32 | #define GSL_EXT_EIGEN_SORT_IMAG 2 33 | #define GSL_EXT_EIGEN_SORT_PHASE 3 34 | int gsl_ext_eigen_sort(gsl_matrix_complex *evec, gsl_vector_complex *eval, int sort_order); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /qdpack/qdpack.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | #ifndef _QDPACK 11 | #define _QDPACK 12 | 13 | #define USE_DENSE 14 | 15 | // 16 | // @mainpage Quantum Dynamics Package 17 | // 18 | // A C library for the time evolution of quantum systems. 19 | // 20 | // @author J Robert Johansson 21 | // 22 | // 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include 42 | 43 | #include 44 | #include 45 | 46 | #include 47 | #include 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /qdpack/states.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for combining density matrices and for tracing out sub-systems from 11 | * full-system density matrices. 12 | */ 13 | 14 | #ifndef STATES_H 15 | #define STATES_H 16 | 17 | #include 18 | 19 | // density matrix 20 | 21 | qdpack_operator_t *qdpack_dm_pure_TLS(double p_ex); 22 | qdpack_operator_t *qdpack_dm_fock_state(int n, int N); 23 | qdpack_operator_t *qdpack_dm_coherent_state(double r, double theta, int N, int offset); 24 | qdpack_operator_t *qdpack_dm_boson_thermal(double w, double w_th, int N); 25 | qdpack_operator_t *qdpack_dm_uniform_superposition(int N); 26 | qdpack_operator_t *qdpack_dm_uniform_mixture(int N); 27 | 28 | 29 | // wave function 30 | 31 | qdpack_state_t *qdpack_wf_fock_state(int n, int N); 32 | qdpack_state_t *qdpack_wf_coherent_state(double r, double theta, int N, int offset); 33 | qdpack_state_t *qdpack_wf_pure_TLS(double p_ex); 34 | 35 | qdpack_state_t *qdpack_wf_superposition(qdpack_state_t *wf1, qdpack_state_t *wf2); 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Copyright (C) 2012, Robert Johansson 3 | # All rights reserved. 4 | # 5 | # This file is part of QDpack, and licensed under the LGPL. 6 | # http://dml.riken.jp/~rob/qdpack.html 7 | #------------------------------------------------------------------------------- 8 | 9 | # ubuntu desktop 10 | CFLAGS= -Wall -I/usr/include/suitesparse -O3 -std=gnu99 -g -Iqdpack -I.. 11 | LDFLAGS=-lm -lumfpack -lamd -lgsl -lf77blas -llapack -lcblas -latlas -lcxsparse 12 | # osx 13 | #CFLAGS= -Wall -I/opt/local/include -O3 -std=gnu99 -g -Iqdpack -I.. 14 | #LDFLAGS=-L/opt/local/lib -lm -lumfpack -lamd -lgsl -llapack -lcblas -lcxsparse 15 | #CC=clang 16 | #CC=gcc 17 | 18 | # bento and tofu clusters 19 | #CFLAGS=-I/beowulf/include/ -I/beowulf/include/amd -Ilib -O3 20 | #LDFLAGS=-L/beowulf/lib -L/beowulf/lib/atlas -llapack -lcblaswr -lm -lF77 -lI77 -lf77blas -lgsl -lcblas -latlas -lumfpack -lamd 21 | 22 | # RSCC 23 | #CFLAGS=-DRSCC 24 | #LDFLAGS=-llapack -latlas -lcblas -lblas -lgsl -lgslcblas -lm 25 | #ARFLAGS=-pc 26 | #CC=cc -gnu2 -static 27 | 28 | all: 29 | (cd qdpack && CC='$(CC)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' make) 30 | (cd examples && CC='$(CC)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' make) 31 | (cd tests && CC='$(CC)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' make) 32 | 33 | install: 34 | (cd qdpack && CC='$(CC)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' make install) 35 | 36 | 37 | doc: 38 | doxygen config.dox 39 | 40 | clean: 41 | (cd qdpack && make clean) 42 | (cd examples && make clean) 43 | -------------------------------------------------------------------------------- /qdpack/simulation.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /** 10 | * @file simulation.c 11 | * 12 | * @brief Functions for managing the qdpack simulation object. 13 | * 14 | * @author J Robert Johansson 15 | * 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | // 23 | // initialize the default parameter values: 24 | // 25 | void 26 | qdpack_simulation_init(qdpack_simulation_t *sp) 27 | { 28 | if (sp) 29 | { 30 | memset((void *)sp, 0, sizeof(qdpack_simulation_t)); 31 | 32 | sp->cont_basis_transform = 0; 33 | sp->option_me_eb = 0; 34 | sp->option_adaptive = 1; 35 | 36 | sp->H0 = NULL; 37 | sp->H1 = NULL; 38 | sp->H_t = NULL; 39 | 40 | sp->H0_func = NULL; 41 | sp->H1_func = NULL; 42 | sp->Ht_func = NULL; 43 | 44 | sp->h_td_A = 0.0; 45 | sp->h_td_w = 0.0; 46 | } 47 | 48 | return; 49 | } 50 | 51 | void 52 | qdpack_simulation_free(qdpack_simulation_t *sp) 53 | { 54 | if (sp) 55 | { 56 | if (sp->H0) qdpack_operator_free(sp->H0); 57 | if (sp->H1) qdpack_operator_free(sp->H1); 58 | //if (sp->H_t) qdpack_operator_free(sp->H_t); 59 | } 60 | 61 | return; 62 | } 63 | -------------------------------------------------------------------------------- /tests/dm_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | #include "quantum_system.h" 8 | #include "density_matrix.h" 9 | #include "operators.h" 10 | #include "misc.h" 11 | 12 | #include 13 | #include 14 | 15 | 16 | int 17 | main(int argc, char **argv) 18 | { 19 | gsl_matrix *sx1, *sx2, *sz1, *sz2, *u, *rho1, *rho2; 20 | gsl_matrix_complex *dm_full, *dm_part; 21 | quantum_system *qs; 22 | quantum_system_state_vector_t qsv; 23 | density_matrix_list_t dm_list; 24 | int qsn, i; 25 | 26 | qs = quantum_system_new(); 27 | quantum_system_add(qs, 2); 28 | 29 | qsn = quantum_system_nstates(qs); 30 | sx1 = operator_sigma_x(qs, 0); 31 | u = operator_unit(qs,0); 32 | 33 | rho1 = density_matrix_pure_TLS(0.74, 0.26); 34 | rho2 = density_matrix_pure_TLS(0.5, 0.5); 35 | 36 | quantum_system_add(qs, 2); 37 | // quantum_system_add(qs, 2); 38 | // quantum_system_add(qs, 2); 39 | qsn = quantum_system_nstates(qs); 40 | quantum_system_print(qs); 41 | 42 | density_matrix_list_init(&dm_list); 43 | density_matrix_list_append(&dm_list, rho1); 44 | density_matrix_list_append(&dm_list, rho2); 45 | // density_matrix_list_append(&dm_list, u); 46 | // density_matrix_list_append(&dm_list, u); 47 | 48 | dm_full = density_matrix_combine(qs, &dm_list); 49 | 50 | printf("dm_full =\n"); 51 | misc_matrix_complex_print(dm_full, qsn); 52 | 53 | for (i = 0; i < qs->nsubsys; i++) 54 | { 55 | dm_part = density_matrix_traceout(qs, dm_full, i); 56 | printf("dm_part[%d] =\n", i); 57 | misc_matrix_complex_print(dm_part, qs->nstates[i]); 58 | gsl_matrix_complex_free(dm_part); 59 | } 60 | 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /tests/test_sparse_matrix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test sparse matrix extention. 3 | * 4 | * JRJ, 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "misc.h" 19 | #include "gsl_ext_sparse.h" 20 | 21 | int 22 | main(int argc, char **argv) 23 | { 24 | int i, j, n = 10, k, K = 30; 25 | gsl_matrix_complex *M_dense; 26 | gsl_sparse_matrix_complex *M_sparse; 27 | 28 | srand(time(NULL)); 29 | 30 | M_sparse = gsl_sparse_matrix_complex_alloc(n,n,n); 31 | 32 | /* 33 | * Create random matrix: 34 | * 35 | */ 36 | for (k = 0; k < K; k++) 37 | { 38 | gsl_complex z; 39 | 40 | i = rand() % n; 41 | j = rand() % n; 42 | 43 | z = gsl_sparse_matrix_complex_get(M_sparse, i, j); 44 | 45 | GSL_SET_COMPLEX(&z, 1.0 + GSL_REAL(z), 1.0 + GSL_IMAG(z)); 46 | 47 | gsl_sparse_matrix_complex_set(M_sparse, i, j, z); 48 | } 49 | 50 | // print sparse in column form 51 | gsl_sparse_matrix_complex_print_triplet(M_sparse); 52 | 53 | // convert from triplet to column format 54 | gsl_sparse_matrix_complex_convert_col(M_sparse); 55 | 56 | // print sparse in column form 57 | gsl_sparse_matrix_complex_print_col(M_sparse); 58 | 59 | // convert to dense 60 | M_dense = gsl_sparse_matrix_complex_convert_to_dense(M_sparse); 61 | 62 | printf("real M = \n"); 63 | misc_matrix_complex_print_real(M_dense, n); 64 | printf("imag M = \n"); 65 | misc_matrix_complex_print_real(M_dense, n); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /tests/expm_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | #include "quantum_system.h" 8 | #include "density_matrix.h" 9 | #include "operators.h" 10 | #include "misc.h" 11 | #include "math.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | int 19 | main(int argc, char **argv) 20 | { 21 | gsl_matrix *sx1, *sx2, *sz1, *sz2, *u, *rho1, *rho2; 22 | gsl_matrix_complex *dm_full, *dm_part, *expm_test; 23 | quantum_system *qs; 24 | quantum_system_state_vector_t qsv; 25 | density_matrix_list_t dm_list; 26 | int qsn, i; 27 | gsl_complex z; 28 | 29 | qs = quantum_system_new(); 30 | quantum_system_add(qs, 2); 31 | 32 | qsn = quantum_system_nstates(qs); 33 | sx1 = operator_sigma_x(qs, 0); 34 | u = operator_unit(qs,0); 35 | 36 | rho1 = density_matrix_pure_TLS(0.74, 0.26); 37 | rho2 = density_matrix_pure_TLS(0.5, 0.5); 38 | 39 | quantum_system_add(qs, 2); 40 | qsn = quantum_system_nstates(qs); 41 | quantum_system_print(qs); 42 | 43 | density_matrix_list_init(&dm_list); 44 | density_matrix_list_append(&dm_list, rho1); 45 | density_matrix_list_append(&dm_list, rho2); 46 | 47 | dm_full = density_matrix_combine(qs, &dm_list); 48 | 49 | printf("dm_full =\n"); 50 | misc_matrix_complex_print(dm_full, qsn); 51 | 52 | expm_test = gsl_matrix_complex_alloc(qsn, qsn); 53 | 54 | math_expm_complex(dm_full, expm_test); 55 | printf("expm_test =\n"); 56 | misc_matrix_complex_print(expm_test, qsn); 57 | 58 | GSL_SET_COMPLEX(&z, 0.0, 1.0); 59 | gsl_matrix_complex_scale(dm_full, z); 60 | 61 | math_expm_complex(dm_full, expm_test); 62 | printf("expm_test_real =\n"); 63 | misc_matrix_complex_print(expm_test, qsn); 64 | printf("expm_test_imag =\n"); 65 | misc_matrix_complex_print_imag(expm_test, qsn); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /qdpack/composite.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for combining density matrices and for tracing out sub-systems from 11 | * full-system density matrices. 12 | */ 13 | 14 | #ifndef COMPOSITE_H 15 | #define COMPOSITE_H 16 | 17 | #include 18 | 19 | typedef struct { 20 | qdpack_operator_t *dm[NQS_MAX]; 21 | int len; 22 | } qdpack_operator_list_t; 23 | 24 | typedef struct { 25 | qdpack_state_t *wf[NQS_MAX]; 26 | int len; 27 | } qdpack_state_list_t; 28 | 29 | 30 | // density matrix 31 | 32 | void qdpack_operator_list_init(qdpack_operator_list_t *dm_list); 33 | void qdpack_operator_list_append(qdpack_operator_list_t *dm_list, qdpack_operator_t *dm); 34 | void qdpack_operator_list_free_entries(qdpack_operator_list_t *dm_list); 35 | int qdpack_operator_tensor(qdpack_operator_t *dm, qdpack_hilbert_space_t *qs, qdpack_operator_list_t *dm_list); 36 | 37 | qdpack_operator_t *qdpack_operator_traceout(qdpack_hilbert_space_t *qs, qdpack_operator_t *dm, int n); 38 | qdpack_operator_t *qdpack_operator_traceout_multi(qdpack_hilbert_space_t *qs, qdpack_operator_t *dm, qdpack_hilbert_space_t *mask); 39 | 40 | // wave function 41 | 42 | void qdpack_wf_list_init(qdpack_state_list_t *wf_list); 43 | void qdpack_wf_list_append(qdpack_state_list_t *wf_list, qdpack_state_t *wf); 44 | void qdpack_wf_list_free_entries(qdpack_state_list_t *wf_list); 45 | int qdpack_wf_tensor(qdpack_state_t *wf, qdpack_hilbert_space_t *qs, qdpack_state_list_t *wf_list); 46 | 47 | qdpack_operator_t *qdpack_wf_traceout(qdpack_hilbert_space_t *qs, qdpack_state_t *wf, int n); 48 | 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /qdpack/hilbert_space.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions related to definition of quantum systems (composed of subsystems 11 | * with different sizes) and enummeration of states 12 | */ 13 | 14 | #include 15 | 16 | #ifndef QUANTUM_SYSTEM_H 17 | #define QUANTUM_SYSTEM_H 18 | 19 | #define NQS_MAX 20 20 | 21 | typedef int qdpack_hilbert_space_state_vector_t[NQS_MAX]; 22 | 23 | typedef struct { 24 | /* system 0: 2 levels 25 | * system 1: 2 levels 26 | * system 3: 10 levels 27 | * etc. 28 | */ 29 | 30 | /* Number of subsystems in the quantum system */ 31 | int nsubsys; 32 | 33 | /* Number of states of each subsystem */ 34 | int *nstates; 35 | } qdpack_hilbert_space_t; 36 | 37 | int ss_idx_major(int N, int a, int b); 38 | int ss_idx_minor_ms(int N, int J); 39 | int ss_idx_minor_ls(int N, int J); 40 | 41 | qdpack_hilbert_space_t * qdpack_hilbert_space_new(); 42 | qdpack_hilbert_space_t * qdpack_hilbert_space_copy(qdpack_hilbert_space_t *qs); 43 | void qdpack_hilbert_space_print(qdpack_hilbert_space_t *qs); 44 | void qdpack_hilbert_space_free(qdpack_hilbert_space_t *qs); 45 | void qdpack_hilbert_space_add(qdpack_hilbert_space_t *qs, int M); 46 | int qdpack_hilbert_space_nstates(qdpack_hilbert_space_t *qs); 47 | void qdpack_hilbert_space_state_vector(qdpack_hilbert_space_t *qs, int qsn, qdpack_hilbert_space_state_vector_t qsv); 48 | int qdpack_hilbert_space_state_number(qdpack_hilbert_space_t *qs, qdpack_hilbert_space_state_vector_t qsv); 49 | 50 | qdpack_hilbert_space_t *qdpack_hilbert_subspace_get(qdpack_hilbert_space_t *qs, int n); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /qdpack/io.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * A collection of various functions. Printing, saving to file, etc. 11 | */ 12 | 13 | #ifndef MISC_H 14 | #define MISC_H 15 | 16 | #include 17 | 18 | // matrix print 19 | // void qdpack_matrix_print(qdpack_matrix *m); 20 | 21 | void qdpack_operator_print(qdpack_operator_t *m); 22 | void qdpack_operator_print_real(qdpack_operator_t *m); 23 | void qdpack_operator_print_imag(qdpack_operator_t *m); 24 | void qdpack_operator_print_abs2(qdpack_operator_t *m); 25 | 26 | // vector print 27 | //void qdpack_state_print(qdpack_state_t *m); 28 | //void qdpack_state_print(qdpack_state_t *v); 29 | void qdpack_state_print_real(qdpack_state_t *v); 30 | void qdpack_state_print_imag(qdpack_state_t *v); 31 | 32 | 33 | // 34 | // row based file io 35 | // 36 | int qdpack_file_row_add(const char *filename, const char *row); 37 | 38 | // 39 | // qdpack operator file io 40 | // 41 | int qdpack_operator_write_real(char *filename, qdpack_operator_t *m); 42 | int qdpack_operator_write_imag(char *filename, qdpack_operator_t *m); 43 | 44 | int qdpack_operator_write(char *filename, qdpack_operator_t *m); 45 | int qdpack_operator_read(char *filename, qdpack_operator_t *m); 46 | 47 | int qdpack_operator_write_double(char *filename, qdpack_operator_t *m, int real); 48 | 49 | int qdpack_operator_diag_write(char *filename, qdpack_operator_t *m, char *msg); 50 | int qdpack_operator_diag_read(char *filename, qdpack_operator_t *m); 51 | int qdpack_operator_diag_real_write(char *filename, qdpack_operator_t *m, char *msg); 52 | int qdpack_operator_diag_real_read(char *filename, qdpack_operator_t *m); 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /tests/test_matrix_backend.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test matrix read and write to file operations. 3 | * 4 | * 5 | * JRJ, 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | int 16 | main(int argc, char **argv) 17 | { 18 | int i, j, n = 10; 19 | 20 | qdpack_complex z; 21 | 22 | qdpack_matrix_t *m1, *m2, *m3; 23 | qdpack_matrix_t *v1, *v2; 24 | 25 | srand(time(NULL)); 26 | 27 | m1 = qdpack_matrix_alloc(n,n); 28 | m2 = qdpack_matrix_alloc(n,n); 29 | m3 = qdpack_matrix_alloc(n,n); 30 | 31 | v1 = qdpack_matrix_alloc(n,1); 32 | v2 = qdpack_matrix_alloc(n,1); 33 | 34 | for (i = 0; i < n; i++) 35 | { 36 | for (j = 0; j < n; j++) 37 | { 38 | QDPACK_SET_COMPLEX(&z, rand() / 128.0, rand() / 128.0); 39 | qdpack_matrix_set(m1, i, j, z); 40 | 41 | QDPACK_SET_COMPLEX(&z, rand() / 128.0, rand() / 128.0); 42 | qdpack_matrix_set(m2, i, j, z); 43 | } 44 | 45 | qdpack_matrix_set(v1, i, 0, qdpack_complex_rect(rand() / 128.0, rand() / 128.0)); 46 | } 47 | 48 | printf("m1 = \n"); 49 | qdpack_matrix_write(stdout, m1, 0); 50 | 51 | printf("m2 = \n"); 52 | qdpack_matrix_write(stdout, m2, 0); 53 | 54 | printf("v1 = \n"); 55 | qdpack_matrix_write(stdout, v1, 0); 56 | 57 | // 58 | // matrix multiplication 59 | // 60 | qdpack_matrix_multiply(m1, m2, m3); 61 | 62 | printf("m3 = \n"); 63 | qdpack_matrix_write(stdout, m3, 0); 64 | 65 | // 66 | // matrix-vector multiplication 67 | // 68 | qdpack_matrix_multiply(m1, v1, v2); 69 | 70 | printf("v2 = \n"); 71 | qdpack_matrix_write(stdout, v2, 0); 72 | 73 | 74 | // 75 | // vector-matrix-vector multiplication 76 | // 77 | 78 | z = qdpack_matrix_multiply_vmv(m1, v1); 79 | printf("v1.T * m1 * v1 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 80 | 81 | z = qdpack_matrix_multiply_vmv(m1, v2); 82 | printf("v2.T * m1 * v2 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /qdpack/mlib.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * A stand-alone library of math functions. 11 | */ 12 | #ifndef MLIB_H 13 | #define MLIB_H 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | /* 20 | * Polynomials. Hermite polynomials. 21 | */ 22 | struct _poly { 23 | int n; 24 | long double *coeff; 25 | } typedef poly; 26 | 27 | int poly_print(poly *p); 28 | poly *poly_hermite(int N); 29 | poly *poly_new(int n); 30 | int poly_free(poly *p); 31 | long double poly_eval(poly *p, long double z); 32 | 33 | /* 34 | * Factorial and product sequences 35 | */ 36 | unsigned long long fact_l(unsigned long long n); 37 | long double fact_d(long double n); 38 | long double fact_sqrt(long double n); 39 | long double fact_seq(long double s, long double f); 40 | 41 | /* 42 | * various helper functions 43 | */ 44 | #define MAX(a,b) ((a 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * A GSL sparse matrix interface for the UMFPACK library. 11 | * 12 | */ 13 | 14 | #ifndef GSL_EXT_SPARSE_H 15 | #define GSL_EXT_SPARSE_H 16 | 17 | #include "umfpack.h" 18 | 19 | #define SPMAT_TYPE_TRIPLET 0 20 | #define SPMAT_TYPE_COL 1 21 | 22 | typedef struct _gsl_sparse_matrix_complex { 23 | 24 | int n, m; 25 | int type; 26 | 27 | // 28 | // Triplet format arrays: 29 | // 30 | UF_long nelem, nz; 31 | 32 | UF_long *row; 33 | UF_long *col; 34 | double *val_real; 35 | double *val_imag; 36 | 37 | 38 | // 39 | // Column format arrays: 40 | // 41 | UF_long *Ap, *Ai; 42 | double *Ax, *Az; 43 | 44 | double Info [UMFPACK_INFO], Control[UMFPACK_CONTROL]; 45 | 46 | // 47 | // Temporary 48 | // 49 | gsl_matrix_complex *M_dense; 50 | 51 | } gsl_sparse_matrix_complex; 52 | 53 | //int gsl_sparse_matrix_complex_resize(gsl_sparse_matrix_complex *spmat); 54 | 55 | gsl_sparse_matrix_complex * gsl_sparse_matrix_complex_alloc(int n, int m, int nelem); 56 | void gsl_sparse_matrix_complex_free(gsl_sparse_matrix_complex *spmat); 57 | 58 | gsl_complex gsl_sparse_matrix_complex_get(gsl_sparse_matrix_complex *spmat, long i, long j); 59 | int gsl_sparse_matrix_complex_set(gsl_sparse_matrix_complex *spmat, long i, long j, gsl_complex z); 60 | 61 | gsl_matrix_complex * gsl_sparse_matrix_complex_convert_to_dense(gsl_sparse_matrix_complex *spmat); 62 | int gsl_sparse_matrix_complex_convert_col(gsl_sparse_matrix_complex *spmat); 63 | 64 | 65 | int gsl_sparse_matrix_complex_print_col(gsl_sparse_matrix_complex *spmat); 66 | int gsl_sparse_matrix_complex_print_triplet(gsl_sparse_matrix_complex *spmat); 67 | 68 | 69 | 70 | int gsl_sparse_matrix_complex_LU_solve(gsl_sparse_matrix_complex *spmat, double *b_real, double *b_imag, double *x_real, double *x_imag); 71 | 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /qdpack/master_equation.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for generating hamiltonians in matrix form 11 | */ 12 | 13 | #ifndef MASTER_EQUATION_H 14 | #define MASTER_EQUATION_H 15 | 16 | #include "hilbert_space.h" 17 | #include "simulation.h" 18 | 19 | // spectral density callback function 20 | typedef double (*spectral_density_cb_t)(qdpack_simulation_t *sp, double f); 21 | 22 | // density matrix solvers 23 | typedef int (*operator_cb_func_t)(qdpack_simulation_t *sp, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho_t, double t); 24 | 25 | int qdpack_evolve_dm_unitary_const (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho0, operator_cb_func_t rho_cb_func); 26 | int qdpack_evolve_dm_unitary_const_simple(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho0, operator_cb_func_t rho_cb_func); 27 | int qdpack_evolve_dm_unitary (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho0, operator_cb_func_t rho_cb_func); 28 | 29 | int qdpack_evolve_dm_lme (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho0, operator_cb_func_t rho_cb_func); 30 | int qdpack_evolve_dm_lme_ib (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho0, operator_cb_func_t rho_cb_func); 31 | 32 | int qdpack_propagator_dm (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *U, operator_cb_func_t rho_cb_func); 33 | 34 | // wave function solvers 35 | typedef int (*state_cb_func_t)(qdpack_simulation_t *sp, qdpack_hilbert_space_t *qs, qdpack_state_t *psi_t, double t); 36 | 37 | int qdpack_evolve_wf (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_state_t *psi0, state_cb_func_t psi_cb_func); 38 | 39 | int qdpack_propagator (qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *U, state_cb_func_t psi_cb_func); 40 | 41 | // monte carlo 42 | int qdpack_evolve_wfmc(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_state_t *psi0, state_cb_func_t psi_cb_func); 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /qdpack/operators.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for generating matrix representations of quantum operators. 11 | */ 12 | 13 | #ifndef OPERATORS_H 14 | #define OPERATORS_H 15 | 16 | #include 17 | 18 | // Qubit / 2LS operators 19 | int operator_sigma_z(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 20 | int operator_sigma_x(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 21 | int operator_sigma_y(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 22 | int operator_sigma_plus(qdpack_operator_t *a, qdpack_hilbert_space_t *qs, int n); 23 | int operator_sigma_minus(qdpack_operator_t *a, qdpack_hilbert_space_t *qs, int n); 24 | 25 | // 3LS operators 26 | int operator_3ls_sigma_z(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 27 | int operator_3ls_sigma_x(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 28 | 29 | 30 | // DQD 3-level operators 31 | int operator_dqd_sigma_z(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 32 | int operator_dqd_sigma_x(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 33 | int operator_dqd_sigma_y(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 34 | 35 | 36 | // large spin operators 37 | int operator_J_minus(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, double jj); 38 | int operator_J_plus (qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, double jj); 39 | int operator_Jz (qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, double jj); 40 | 41 | // harmonic oscillator operators 42 | int operator_ho_lowering(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, int offset); 43 | int operator_ho_raising(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, int offset); 44 | int operator_ho_N(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, int offset); 45 | 46 | // generic operators 47 | int operator_project(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n, int si, int sj); 48 | int operator_unit(qdpack_operator_t *op, qdpack_hilbert_space_t *qs, int n); 49 | 50 | qdpack_complex operator_trace(qdpack_operator_t *op); 51 | 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /tests/test_matrix_backend_gsl.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | int 17 | main(int argc, char **argv) 18 | { 19 | int i, j, n = 5; 20 | 21 | qdpack_complex z; 22 | 23 | qdpack_matrix_t *m1, *m2, *m3; 24 | qdpack_matrix_t *v1, *v2; 25 | 26 | srand(time(NULL)); 27 | 28 | m1 = qdpack_matrix_alloc(n,n); 29 | m2 = qdpack_matrix_alloc(n,n); 30 | m3 = qdpack_matrix_alloc(n,n); 31 | 32 | v1 = qdpack_matrix_alloc(n,1); 33 | v2 = qdpack_matrix_alloc(n,1); 34 | 35 | for (i = 0; i < n; i++) 36 | { 37 | for (j = 0; j < n; j++) 38 | { 39 | qdpack_matrix_set(m1, i, j, qdpack_complex_rect(rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX))); 40 | qdpack_matrix_set(m2, i, j, qdpack_complex_rect(rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX))); 41 | } 42 | 43 | qdpack_matrix_set(v1, i, 0, qdpack_complex_rect(rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX))); 44 | } 45 | 46 | printf("\nm1 = \n"); 47 | qdpack_matrix_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 48 | 49 | printf("\nm2 = \n"); 50 | qdpack_matrix_write(stdout, m2, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 51 | 52 | printf("\nv1 = \n"); 53 | qdpack_matrix_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 54 | 55 | // 56 | // matrix multiplication 57 | // 58 | qdpack_matrix_multiply(m1, m2, m3); 59 | 60 | printf("\nm3 = \n"); 61 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 62 | 63 | // 64 | // matrix-vector multiplication 65 | // 66 | qdpack_matrix_multiply(m1, v1, v2); 67 | 68 | printf("\nv2 = \n"); 69 | qdpack_matrix_write(stdout, v2, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 70 | 71 | 72 | // 73 | // vector-matrix-vector multiplication 74 | // 75 | 76 | z = qdpack_matrix_multiply_vmv(m1, v1); 77 | printf("\nv1.T * m1 * v1 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 78 | 79 | z = qdpack_matrix_multiply_vmv(m1, v2); 80 | printf("\nv2.T * m1 * v2 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /tests/test_matrix_backend_cxsparse_conversion.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | int 17 | main(int argc, char **argv) 18 | { 19 | int i, j, n = 3; 20 | 21 | qdpack_matrix_t *m1; 22 | qdpack_matrix_t *v1; 23 | 24 | m1 = qdpack_matrix_alloc(n,n); 25 | v1 = qdpack_matrix_alloc(n,1); 26 | 27 | srand(time(NULL)); 28 | 29 | for (i = 0; i < n; i++) 30 | { 31 | for (j = 0; j < n; j++) 32 | { 33 | qdpack_matrix_set(m1, i, j, qdpack_complex_rect(rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX))); 34 | } 35 | qdpack_matrix_set(v1, i, 0, qdpack_complex_rect(rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX))); 36 | } 37 | 38 | // 39 | // matrix 40 | // 41 | 42 | printf("\nm1 = \n"); 43 | qdpack_matrix_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 44 | qdpack_matrix_sparse_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 45 | 46 | qdpack_matrix_compressed(m1); 47 | 48 | printf("\nm1 = \n"); 49 | qdpack_matrix_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 50 | qdpack_matrix_sparse_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 51 | 52 | qdpack_matrix_triplet(m1); 53 | 54 | printf("\nm1 = \n"); 55 | qdpack_matrix_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 56 | qdpack_matrix_sparse_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 57 | 58 | // 59 | // vector 60 | // 61 | 62 | printf("\nv1 = \n"); 63 | qdpack_matrix_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 64 | qdpack_matrix_sparse_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 65 | 66 | qdpack_matrix_compressed(v1); 67 | 68 | printf("\nv1 = \n"); 69 | qdpack_matrix_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 70 | qdpack_matrix_sparse_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 71 | 72 | qdpack_matrix_triplet(m1); 73 | 74 | printf("\nv1 = \n"); 75 | qdpack_matrix_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 76 | qdpack_matrix_sparse_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 77 | 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /qdpack/distribution_functions.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | 10 | #ifndef DIST_FUNCS_H 11 | #define DIST_FUNCS_H 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "qdpack.h" 18 | 19 | int distribution_function_Q(qdpack_matrix_t *Q, qdpack_operator_t *rho, double alpha_max); 20 | 21 | 22 | int distribution_function_characteristic_w( 23 | qdpack_matrix_t *phase_space, 24 | qdpack_operator_t *a, 25 | qdpack_operator_t *ad, 26 | qdpack_operator_t *rho, 27 | qdpack_complex lambda_max); 28 | 29 | double cb_integrand_wigner_cf(qdpack_complex lambda, qdpack_matrix_t *phase_space_cf, qdpack_complex alpha); 30 | 31 | int distribution_function_wigner_cf_quad( 32 | qdpack_matrix_t *phase_space_wigner, 33 | qdpack_operator_t *a, 34 | qdpack_operator_t *ad, 35 | qdpack_operator_t *rho, 36 | qdpack_complex alpha_max); 37 | 38 | int distribution_function_wigner_cf_sum( 39 | qdpack_matrix_t *phase_space_wigner, 40 | qdpack_operator_t *a, 41 | qdpack_operator_t *ad, 42 | qdpack_operator_t *rho, 43 | qdpack_complex alpha_max); 44 | 45 | int distribution_function_wigner_cf_fft( 46 | qdpack_matrix_t *phase_space_wigner, 47 | qdpack_operator_t *a, 48 | qdpack_operator_t *ad, 49 | qdpack_operator_t *rho, 50 | qdpack_complex alpha_max); 51 | 52 | typedef struct _wigner_hermite_data { 53 | double p; 54 | double q; 55 | qdpack_operator_t *rho; 56 | int N; 57 | } wigner_hermite_data_t; 58 | 59 | typedef struct _wigner_data { 60 | double p; 61 | double q; 62 | 63 | qdpack_matrix_t *Cw; 64 | 65 | qdpack_complex lambda, alpha; 66 | qdpack_complex lambda_max, alpha_max; 67 | 68 | qdpack_operator_t *rho; 69 | 70 | gsl_function f_re, f_im; 71 | 72 | gsl_integration_workspace *w_re, *w_im; 73 | gsl_integration_qawo_table *wf_re, *wf_im; 74 | 75 | int N; 76 | 77 | 78 | } wigner_data_t; 79 | 80 | double cb_integrand_wigner_hermite(double x, void *data); 81 | int distribution_function_wigner_hermite_quad( 82 | qdpack_matrix_t *phase_space_wigner, 83 | qdpack_operator_t *rho, 84 | double x_limit); 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /tests/test_matrix_fops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test matrix read and write to file operations. 3 | * 4 | * 5 | * JRJ, 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | int 16 | main(int argc, char **argv) 17 | { 18 | //char *filename = "matrix.dat"; 19 | int i, j, n = 10; 20 | qdpack_matrix_t *orig, *copy; 21 | 22 | srand(time(NULL)); 23 | 24 | orig = qdpack_matrix_alloc(n,n); 25 | copy = qdpack_matrix_alloc(n,n); 26 | 27 | /* 28 | * Create random matrix: 29 | * 30 | */ 31 | for (i = 0; i < n; i++) 32 | { 33 | for (j = 0; j < n; j++) 34 | { 35 | qdpack_complex z; 36 | QDPACK_SET_COMPLEX(&z, rand() / 128.0, rand() / 128.0); 37 | qdpack_matrix_set(orig, i, j, z); 38 | } 39 | } 40 | 41 | printf("orig = \n"); 42 | qdpack_matrix_write(stdout, orig, 0); 43 | 44 | /* 45 | * Write matrix to file: 46 | */ 47 | //XXX misc_matrix_write(filename, orig, n); 48 | 49 | //XXX misc_matrix_read(filename, copy, n); 50 | 51 | printf("copy = \n"); 52 | qdpack_matrix_write(stdout, copy, 0); 53 | 54 | /* 55 | * Compare matrices: 56 | * 57 | */ 58 | for (i = 0; i < n; i++) 59 | { 60 | for (j = 0; j < n; j++) 61 | { 62 | qdpack_complex zo, zc; 63 | 64 | zo = qdpack_matrix_get(orig, i, j); 65 | zc = qdpack_matrix_get(copy, i, j); 66 | 67 | if (fabs(QDPACK_REAL(zo) - QDPACK_REAL(zc)) > 0.0001 || 68 | fabs(QDPACK_IMAG(zo) - QDPACK_IMAG(zc)) > 0.0001) 69 | { 70 | printf("Error: readback missmatch at location [%d, %d]\n", i, j); 71 | } 72 | } 73 | } 74 | 75 | /* 76 | * Write matrix to file: 77 | * / 78 | misc_matrix_diag_write(filename, orig, n, ""); 79 | 80 | misc_matrix_diag_read(filename, copy, n); 81 | 82 | printf("copy = \n"); 83 | misc_matrix_complex_print_real(copy, n); 84 | 85 | / * 86 | * Write matrix to file: 87 | * / 88 | misc_matrix_diag_real_write(filename, orig, n, ""); 89 | 90 | misc_matrix_diag_real_read(filename, copy, n); 91 | 92 | printf("copy = \n"); 93 | misc_matrix_complex_print_real(copy, n); 94 | 95 | 96 | return 0; 97 | 98 | 99 | / * 100 | * Compare matrices: 101 | * 102 | * / 103 | for (i = 0; i < n; i++) 104 | { 105 | for (j = 0; j < n; j++) 106 | { 107 | gsl_complex zo, zc; 108 | 109 | zo = gsl_matrix_complex_get(orig, i, j); 110 | zc = gsl_matrix_complex_get(copy, i, j); 111 | 112 | if ( fabs(GSL_REAL(zo) - GSL_REAL(zc)) > 0.0001 || 113 | fabs(GSL_IMAG(zo) - GSL_IMAG(zc)) > 0.0001) 114 | { 115 | printf("Error: readback missmatch at location [%d, %d]\n", i, j); 116 | } 117 | } 118 | } 119 | 120 | printf("Test finished.\n"); 121 | */ 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /tests/eigen_cmpl_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test code for computing eigenvalues of a general (non-symmetric) complex matrix. 3 | * 4 | * Example intput: 5 | 6 | 3 7 | (0.816417425405234,0.144827013835311) (0.324151253793389,0.523759318049997) (0.303578688297421,0.976534355431795) 8 | (0.181262716185302,0.117307899985462) (0.261452937033027,0.0836455137468874) (0.374216732569039,0.696820253506303) 9 | (0.538486659061164,0.929988969117403) (0.865246564149857,0.289147571194917) (0.855454510543495,0.186055930331349) 10 | 11 | * 12 | * Complile: 13 | 14 | gcc eigen_cmpl_test.c gsl_ext.c -o eigen_cmpl_test -L/usr/local/lib/lapack/ -llapack -lblas -lm -lF77 -lI77 -I/usr/local/include/lapack -lgsl -lcblas 15 | 16 | 17 | * Robert Johansson, 18 | */ 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "gsl_ext.h" 26 | 27 | int 28 | main(int argc, char **argv) 29 | { 30 | int n, i, j; 31 | gsl_matrix_complex *A, *evec; 32 | gsl_vector_complex *eval; 33 | 34 | // Read a complex matrix from stdin and allocate memory 35 | scanf("%d",&n); 36 | printf("\nReading complex matrix of size %dx%d from stdin:\n",n, n); 37 | 38 | A = gsl_matrix_complex_alloc(n,n); 39 | evec = gsl_matrix_complex_alloc(n,n); 40 | eval = gsl_vector_complex_alloc(n); 41 | 42 | for (i = 0; i < n; i++) 43 | { 44 | for (j = 0; j < n; j++) 45 | { 46 | gsl_complex z; 47 | double re, im; 48 | scanf(" (%lf,%lf)", &re, &im); 49 | GSL_SET_COMPLEX(&z, re, im); 50 | gsl_matrix_complex_set(A, i, j, z); 51 | } 52 | } 53 | 54 | printf("A = \n"); 55 | for (i = 0; i < n; i++) 56 | { 57 | for (j = 0; j < n; j++) 58 | { 59 | gsl_complex z; 60 | z = gsl_matrix_complex_get(A, i, j); 61 | printf(" (%.15g,%.15g)", GSL_REAL(z), GSL_IMAG(z)); 62 | } 63 | printf("\n"); 64 | } 65 | 66 | // Start calculating eigen values and eigen vectors 67 | gsl_ext_eigen_zgeev(A, evec, eval); 68 | 69 | printf("Eigenvalues = \n"); 70 | for (i = 0; i < n; i++) 71 | { 72 | gsl_complex z; 73 | z = gsl_vector_complex_get(eval, i); 74 | printf("\t(%f, %f)", GSL_REAL(z), GSL_IMAG(z)); 75 | } 76 | printf("\n"); 77 | 78 | printf("evec = \n"); 79 | for (i = 0; i < n; i++) 80 | { 81 | for (j = 0; j < n; j++) 82 | { 83 | gsl_complex z; 84 | z = gsl_matrix_complex_get(evec, i, j); 85 | printf("\t(%f, %f)", GSL_REAL(z), GSL_IMAG(z)); 86 | } 87 | printf("\n"); 88 | } 89 | 90 | /* 91 | for (j = 0; j < n; j++) 92 | { 93 | printf("Eigenvector%d = \n", j); 94 | for (i = 0; i < n; i++) 95 | { 96 | gsl_complex z; 97 | z = gsl_matrix_complex_get(evec, i, j); 98 | printf("\t(%f, %f)", GSL_REAL(z), GSL_IMAG(z)); 99 | } 100 | printf("\n"); 101 | } 102 | */ 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /qdpack/integrate.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions for integration of systems of differential equations. 11 | */ 12 | 13 | #ifndef INTEGRATE_H 14 | #define INTEGRATE_H 15 | 16 | #include 17 | 18 | #define RK_REC_MAX_LEVEL 15 19 | 20 | // 21 | // operator integration 22 | // 23 | typedef int (*ode_operator_func_d_dt)(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *rho_t, qdpack_operator_t *drho_dt, double t); 24 | 25 | int odeint_operator_rk(qdpack_simulation_t *sim, 26 | qdpack_hilbert_space_t *qs, 27 | qdpack_operator_t *rho0, 28 | ode_operator_func_d_dt f_d_dt, 29 | operator_cb_func_t rho_cb_func); 30 | 31 | int odeint_operator_rk_adaptive(qdpack_simulation_t *sim, 32 | qdpack_hilbert_space_t *qs, 33 | qdpack_operator_t *rho0, 34 | ode_operator_func_d_dt f_d_dt, 35 | operator_cb_func_t rho_cb_func); 36 | 37 | int odeint_operator_rk_adaptive_rec(qdpack_simulation_t *sim, 38 | qdpack_hilbert_space_t *qs, 39 | ode_operator_func_d_dt f_d_dt, 40 | qdpack_operator_t *rho0, 41 | qdpack_operator_t *rho_final, 42 | int level, double ti, double tf, double etol, double *e); 43 | 44 | double operator_max_deviation(qdpack_operator_t *m1, qdpack_operator_t *m2, double etol); 45 | 46 | 47 | // 48 | // state vector integration 49 | // 50 | typedef int (*ode_state_func_d_dt)(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_state_t *psi_t, qdpack_state_t *dpsi_dt, double t); 51 | 52 | int odeint_state_rk(qdpack_simulation_t *sim, 53 | qdpack_hilbert_space_t *qs, 54 | qdpack_state_t *psi0, 55 | ode_state_func_d_dt f_d_dt, 56 | state_cb_func_t psi_cb_func); 57 | 58 | int odeint_state_rk_adaptive(qdpack_simulation_t *sim, 59 | qdpack_hilbert_space_t *qs, 60 | qdpack_state_t *psi0, 61 | ode_state_func_d_dt f_d_dt, 62 | state_cb_func_t psi_cb_func); 63 | 64 | int odeint_state_rk_adaptive_rec(qdpack_simulation_t *sim, 65 | qdpack_hilbert_space_t *qs, 66 | ode_state_func_d_dt f_d_dt, 67 | qdpack_state_t *psi0, 68 | qdpack_state_t *psi_final, 69 | int level, double ti, double tf, double etol, double *e); 70 | 71 | double state_max_deviation(qdpack_state_t *m1, qdpack_state_t *m2, double etol); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /install-ubuntu.txt: -------------------------------------------------------------------------------- 1 | 2 | Install the following packages: 3 | 4 | sudo apt-get install liblapack-dev 5 | sudo apt-get install libatlas-base-dev 6 | sudo apt-get install libgsl0-dev 7 | sudo apt-get install libgsl0-dbg 8 | sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev libatlas3gf-sse2 9 | sudo apt-get install libf2c2 libf2c2-dev f2c 10 | sudo apt-get install libsuitesparse-dev 11 | 12 | To build the simulation code by running "make" on the command line: 13 | 14 | rob@rob01$ make 15 | (cd lib && make CFLAGS='-I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib' LDFLAGS='-lumfpack -lamd -lgsl -lf77blas -llapack -lcblas -latlas -lm') 16 | make[1]: Entering directory `/home/rob/Desktop/qdpack/lib' 17 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o mlib.o mlib.c 18 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o gsl_ext_expm_complex.o gsl_ext_expm_complex.c 19 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o integrate.o integrate.c 20 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o gsl_ext.o gsl_ext.c 21 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o entanglement.o entanglement.c 22 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o hamiltonian.o hamiltonian.c 23 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o quantum_system.o quantum_system.c 24 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o density_matrix.o density_matrix.c 25 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o operators.o operators.c 26 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o misc.o misc.c 27 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o master_equation.o master_equation.c 28 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o basis_transform.o basis_transform.c 29 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o steadystate.o steadystate.c 30 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o gsl_ext_sparse.o gsl_ext_sparse.c 31 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o steadystate_sparse.o steadystate_sparse.c 32 | cc -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -c -o distribution_functions.o distribution_functions.c 33 | ar rv libqd.a mlib.o gsl_ext_expm_complex.o gsl_ext_expm_complex.o integrate.o gsl_ext.o entanglement.o hamiltonian.o quantum_system.o density_matrix.o operators.o misc.o master_equation.o basis_transform.o steadystate.o gsl_ext_sparse.o steadystate_sparse.o distribution_functions.o 34 | ar: creating libqd.a 35 | a - mlib.o 36 | a - gsl_ext_expm_complex.o 37 | a - gsl_ext_expm_complex.o 38 | a - integrate.o 39 | a - gsl_ext.o 40 | a - entanglement.o 41 | a - hamiltonian.o 42 | a - quantum_system.o 43 | a - density_matrix.o 44 | a - operators.o 45 | a - misc.o 46 | a - master_equation.o 47 | a - basis_transform.o 48 | a - steadystate.o 49 | a - gsl_ext_sparse.o 50 | a - steadystate_sparse.o 51 | a - distribution_functions.o 52 | make[1]: Leaving directory `/home/rob/Desktop/qdpack/lib' 53 | for i in run_2ls_pss run_2ls_sd_range run_ho_ss run_2ls_pss_ni run_2ho_optmech run_2ho_sb_cooling_LG run_qho_dispshift; do \ 54 | echo Building $i; \ 55 | cc -o $i $i.c -I/usr/include/suitesparse -O3 -std=gnu99 -g -Ilib -lumfpack -lamd -lgsl -lf77blas -llapack -lcblas -latlas -lm lib/libqd.a; \ 56 | done 57 | Building run_2ls_pss 58 | Building run_2ls_sd_range 59 | Building run_ho_ss 60 | Building run_2ls_pss_ni 61 | Building run_2ho_optmech 62 | Building run_2ho_sb_cooling_LG 63 | Building run_qho_dispshift 64 | rob@rob01$ 65 | 66 | -------------------------------------------------------------------------------- /qdpack/gsl_ext_rscc.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | 20 | int 21 | gsl_matrix_complex_add_diagonal (gsl_matrix_complex * a, const gsl_complex x) 22 | { 23 | const size_t M = a->size1; 24 | const size_t N = a->size2; 25 | const size_t tda = a->tda; 26 | const size_t loop_lim = (M < N ? M : N); 27 | size_t i; 28 | for (i = 0; i < loop_lim; i++) 29 | { 30 | a->data[2 * (i * tda + i)] += GSL_REAL (x); 31 | a->data[2 * (i * tda + i) + 1] += GSL_IMAG (x); 32 | } 33 | 34 | return GSL_SUCCESS; 35 | } 36 | 37 | 38 | int 39 | gsl_matrix_complex_scale (gsl_matrix_complex * a, const gsl_complex x) 40 | { 41 | const size_t M = a->size1; 42 | const size_t N = a->size2; 43 | const size_t tda = a->tda; 44 | 45 | size_t i, j; 46 | 47 | double xr = GSL_REAL(x); 48 | double xi = GSL_IMAG(x); 49 | 50 | for (i = 0; i < M; i++) 51 | { 52 | for (j = 0; j < N; j++) 53 | { 54 | const size_t aij = 2 * (i * tda + j); 55 | 56 | double ar = a->data[aij]; 57 | double ai = a->data[aij + 1]; 58 | 59 | a->data[aij] = ar * xr - ai * xi; 60 | a->data[aij + 1] = ar * xi + ai * xr; 61 | } 62 | } 63 | 64 | return GSL_SUCCESS; 65 | } 66 | 67 | 68 | int 69 | gsl_matrix_complex_add (gsl_matrix_complex * a, const gsl_matrix_complex * b) 70 | { 71 | const size_t M = a->size1; 72 | const size_t N = a->size2; 73 | 74 | if (b->size1 != M || b->size2 != N) 75 | { 76 | GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); 77 | } 78 | else 79 | { 80 | const size_t tda_a = a->tda; 81 | const size_t tda_b = b->tda; 82 | 83 | size_t i, j; 84 | 85 | for (i = 0; i < M; i++) 86 | { 87 | for (j = 0; j < N; j++) 88 | { 89 | const size_t aij = 2 * (i * tda_a + j); 90 | const size_t bij = 2 * (i * tda_b + j); 91 | 92 | a->data[aij] += b->data[bij]; 93 | a->data[aij + 1] += b->data[bij + 1]; 94 | } 95 | } 96 | 97 | return GSL_SUCCESS; 98 | } 99 | } 100 | 101 | int 102 | gsl_matrix_complex_sub (gsl_matrix_complex * a, const gsl_matrix_complex * b) 103 | { 104 | const size_t M = a->size1; 105 | const size_t N = a->size2; 106 | 107 | if (b->size1 != M || b->size2 != N) 108 | { 109 | GSL_ERROR ("matrices must have same dimensions", GSL_EBADLEN); 110 | } 111 | else 112 | { 113 | const size_t tda_a = a->tda; 114 | const size_t tda_b = b->tda; 115 | 116 | size_t i, j; 117 | 118 | for (i = 0; i < M; i++) 119 | { 120 | for (j = 0; j < N; j++) 121 | { 122 | const size_t aij = 2 * (i * tda_a + j); 123 | const size_t bij = 2 * (i * tda_b + j); 124 | 125 | a->data[aij] -= b->data[bij]; 126 | a->data[aij + 1] -= b->data[bij + 1]; 127 | } 128 | } 129 | 130 | return GSL_SUCCESS; 131 | } 132 | } 133 | 134 | -------------------------------------------------------------------------------- /qdpack/qdpack_object.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // Description: 11 | // 12 | // QDpack objects for operators and state vectors. An abstraction layer between 13 | // the quantum objects and the underlaying matrix representation, allowing for 14 | // alternative matrix packages to be used (GSL, sparse, etc.) 15 | // 16 | 17 | #ifndef _QDPACK_OBJECT 18 | #define _QDPACK_OBJECT 19 | 20 | #include 21 | 22 | typedef struct _qdpack_operator_t { 23 | 24 | int n, m; 25 | 26 | qdpack_hilbert_space_t *qs; 27 | 28 | qdpack_matrix_t *data; 29 | 30 | } qdpack_operator_t; 31 | 32 | typedef struct _qdpack_state { 33 | 34 | // flag for bra or ket 35 | 36 | int n; 37 | 38 | qdpack_hilbert_space_t *qs; 39 | 40 | qdpack_matrix_t *data; 41 | 42 | } qdpack_state_t; 43 | 44 | // state vectors 45 | qdpack_state_t *qdpack_state_alloc(qdpack_hilbert_space_t *qs); 46 | void qdpack_state_free(qdpack_state_t *op); 47 | 48 | qdpack_complex qdpack_state_get(qdpack_state_t *op, size_t i); 49 | void qdpack_state_set(qdpack_state_t *op, size_t i, qdpack_complex value); 50 | 51 | void qdpack_state_memcpy(qdpack_state_t *dst, qdpack_state_t *src); 52 | 53 | void qdpack_state_scale(qdpack_state_t *op, qdpack_complex z); 54 | void qdpack_state_add(qdpack_state_t *op1, qdpack_state_t *op2); 55 | void qdpack_state_sub(qdpack_state_t *op1, qdpack_state_t *op2); 56 | 57 | void qdpack_state_set_zero(qdpack_state_t *op); 58 | 59 | qdpack_complex qdpack_state_expectation_value(qdpack_state_t *wf, qdpack_operator_t *op); 60 | int qdpack_state_to_operator(qdpack_operator_t *rho, qdpack_state_t *wf); 61 | 62 | qdpack_complex qdpack_state_dot(qdpack_state_t *a, qdpack_state_t *b); 63 | 64 | 65 | // operators 66 | qdpack_operator_t *qdpack_operator_alloc(qdpack_hilbert_space_t *qs); 67 | void qdpack_operator_free(qdpack_operator_t *op); 68 | 69 | qdpack_complex qdpack_operator_get(qdpack_operator_t *op, size_t i, size_t j); 70 | void qdpack_operator_set(qdpack_operator_t *op, size_t i, size_t j, qdpack_complex value); 71 | void qdpack_operator_set_all(qdpack_operator_t *op, qdpack_complex value); 72 | void qdpack_operator_set_zero(qdpack_operator_t *op); 73 | void qdpack_operator_set_identity(qdpack_operator_t *op); 74 | 75 | void qdpack_operator_memcpy(qdpack_operator_t *dst, qdpack_operator_t *src); 76 | 77 | void qdpack_operator_scale(qdpack_operator_t *op, qdpack_complex z); 78 | void qdpack_operator_add(qdpack_operator_t *op1, qdpack_operator_t *op2); 79 | void qdpack_operator_sub(qdpack_operator_t *op1, qdpack_operator_t *op2); 80 | 81 | 82 | void qdpack_operator_blas_zgemm(QDPACK_TRANSPOSE_t transA, 83 | QDPACK_TRANSPOSE_t transB, 84 | qdpack_complex alpha, 85 | qdpack_operator_t *A, 86 | qdpack_operator_t *B, 87 | qdpack_complex beta, 88 | qdpack_operator_t *C); 89 | 90 | void qdpack_operator_multiply(qdpack_operator_t *A, qdpack_operator_t *B, qdpack_operator_t *C); 91 | void qdpack_operator_state_multiply(qdpack_operator_t *A, qdpack_state_t *b, qdpack_state_t *c); 92 | 93 | qdpack_complex qdpack_operator_trace(qdpack_operator_t *rho); 94 | qdpack_complex qdpack_operator_expectation_value(qdpack_operator_t *rho, qdpack_operator_t *op); 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /qdpack/simulation.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /** 10 | * @mainpage Quantum Dynamics Package 11 | * 12 | * A C library for time-evolution of quantum systems. 13 | * 14 | * @author J Robert Johansson 15 | * 16 | */ 17 | 18 | /** 19 | * @file simulation.h 20 | * 21 | * @brief Data structure that contains all the parameters and settings for a 22 | * simulation. 23 | * 24 | * @author J Robert Johansson 25 | * 26 | */ 27 | 28 | #ifndef SIMULATION_H 29 | #define SIMULATION_H 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | struct _qdpack_simulation; 37 | 38 | typedef int(*hamiltonian_func_t)(struct _qdpack_simulation *, qdpack_hilbert_space_t *, qdpack_operator_t *); 39 | typedef int(*hamiltonian_td_func_t)(struct _qdpack_simulation *, qdpack_operator_t *, qdpack_operator_t *, qdpack_operator_t *, double); 40 | typedef double(*ho_w_func_t)(double, void*); 41 | 42 | #define H_MAX_TERMS 20 43 | 44 | typedef struct _qdpack_simulation { 45 | 46 | qdpack_hilbert_space_t *qs; 47 | 48 | /* -- time evolution -- */ 49 | double Ti; 50 | double Tf; 51 | double dT; 52 | 53 | //double x, y; 54 | 55 | char simsig[1024]; 56 | 57 | /* --- Temperature in frequency unit --- */ 58 | //double wT; 59 | double T_w; 60 | 61 | qdpack_operator_t *H0; 62 | qdpack_operator_t *H1; 63 | qdpack_operator_t *H_t; 64 | qdpack_operator_t *H_a; 65 | qdpack_operator_t *H_b; 66 | 67 | 68 | /* -- dissipation -- */ 69 | qdpack_operator_t *do_a[H_MAX_TERMS]; 70 | qdpack_operator_t *do_ad[H_MAX_TERMS]; //XXX only used in steady state solver 71 | qdpack_operator_t *do_aad[H_MAX_TERMS]; 72 | qdpack_operator_t *do_ada[H_MAX_TERMS]; 73 | 74 | qdpack_operator_t *do_a_eb[H_MAX_TERMS]; 75 | qdpack_operator_t *do_ad_eb[H_MAX_TERMS]; 76 | qdpack_operator_t *do_aad_eb[H_MAX_TERMS]; 77 | qdpack_operator_t *do_ada_eb[H_MAX_TERMS]; 78 | 79 | qdpack_operator_t *ws1; 80 | qdpack_operator_t *ws2; 81 | qdpack_operator_t *op_tmp; 82 | 83 | double do_g1[H_MAX_TERMS]; 84 | double do_g2[H_MAX_TERMS]; 85 | 86 | int do_n; 87 | 88 | /* --- problem dependent parameters --- */ 89 | 90 | void *parameters; 91 | 92 | /* --- continuous basis transform --- */ 93 | qdpack_operator_t *dSSt; 94 | ho_w_func_t ho_w_func; 95 | 96 | /* --- options --- */ 97 | int cont_basis_transform; 98 | int option_me_eb; 99 | int option_adaptive; 100 | 101 | /* --- Harmonic oscillator --- */ 102 | 103 | double g0, g1, g2; 104 | 105 | qdpack_operator_t *N_op[10], *N2_op[10]; 106 | qdpack_operator_t *a, *ad, *b, *bd, *b2, *bd2, *rho_f, *A, *B; 107 | qdpack_operator_t *n_op, *n_op_2, *x1, *x1_2, *x2, *x2_2; 108 | 109 | qdpack_state_t *psi_f; 110 | 111 | /* -- driving field -- */ 112 | 113 | double h_td_A; 114 | double h_td_w; 115 | //double phi; 116 | 117 | //double Nexpt[2]; 118 | 119 | /* --- hamiltonians --- */ 120 | hamiltonian_func_t H0_func; 121 | hamiltonian_func_t H1_func; 122 | hamiltonian_td_func_t Ht_func; 123 | 124 | 125 | /* --- eigenvalues --- */ 126 | qdpack_operator_t *evec; 127 | qdpack_matrix_t *eval; 128 | 129 | /* --- floquet state --- */ 130 | 131 | qdpack_operator_t *floquet_states_t; 132 | qdpack_operator_t *floquet_modes, *floquet_modes_t; 133 | qdpack_matrix_t *floquet_quasienergies; 134 | 135 | qdpack_operator_t **floquet_X, **floquet_gamma, **floquet_delta, *floquet_A, *floquet_operator; 136 | qdpack_matrix_t *floquet_Gamma; 137 | qdpack_matrix_t *floquet_ss_prob; 138 | 139 | int floquet_k_max; 140 | 141 | } qdpack_simulation_t; 142 | 143 | 144 | void qdpack_simulation_init(qdpack_simulation_t *sp); 145 | void qdpack_simulation_free(qdpack_simulation_t *sp); 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /qdpack/basis_transform.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* 17 | * Generate basis transformation matrix for a harmonic oscillator with 18 | * frequency switch: S 19 | * 20 | * rho_t = S * rho_t0 * S' 21 | * 22 | */ 23 | qdpack_operator_t * 24 | basis_transform(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, int n, ho_w_func_t ho_w_cb, double t) 25 | { 26 | qdpack_complex z; 27 | qdpack_operator_t *S; 28 | int i, j, ns, mm, ll; 29 | double r, w0, wt, sij; 30 | qdpack_operator_list_t op_list; 31 | 32 | ns = qs->nstates[n]; 33 | 34 | if ((S = qdpack_operator_alloc(qs)) == NULL) 35 | { 36 | fprintf(stderr, "basis_transform_ho: Failed to allocate basis tranformation matrix (Out of memory?).\n"); 37 | 38 | } 39 | qdpack_operator_set_zero(S); 40 | 41 | w0 = ho_w_cb(0.0, sim); 42 | wt = ho_w_cb(t, sim); 43 | 44 | r = 2 * sqrt(w0 * wt) / (wt + w0); 45 | if (r > 1.0) 46 | r = 1.0; 47 | else if (r < -1.0) 48 | r = -1.0; 49 | 50 | //printf("DEBUG: basis_transform: r = %f (%f, %f): %f\n", r, w0, wt, t); 51 | 52 | for (j = 0; j < ns; j++) 53 | { 54 | for (i = j; i < ns; i++) 55 | { 56 | if ((i == j) || ((i+j)%2 == 0)) 57 | { 58 | ll = (i+j)/2; 59 | mm = abs(i-j)/2; 60 | sij = fact_sqrt(MIN(i,j)) / fact_sqrt(MAX(i,j)) * sqrt(r) * gsl_sf_legendre_Plm(ll, mm, r); 61 | //if (wt > w0) 62 | QDPACK_SET_COMPLEX(&z, sij, 0.0); 63 | //else 64 | // QDPACK_SET_COMPLEX(&z, -sij, 0.0); 65 | qdpack_operator_set(S, i, j, z); 66 | 67 | if (i != j) 68 | { 69 | sij = pow(-1.0, (j-i)/2.0) * sij; 70 | QDPACK_SET_COMPLEX(&z, sij, 0.0); 71 | qdpack_operator_set(S, j, i, z); 72 | } 73 | } 74 | } 75 | } 76 | 77 | if (qs->nsubsys > 1) 78 | { 79 | qdpack_operator_list_init(&op_list); 80 | 81 | for (i = 0; i < qs->nsubsys; i++) 82 | { 83 | qdpack_operator_t *M; 84 | qdpack_hilbert_space_t *qs_sub = qdpack_hilbert_space_new(); 85 | qdpack_hilbert_space_add(qs_sub, qs->nstates[i]); 86 | 87 | M = qdpack_operator_alloc(qs_sub); 88 | 89 | if (i != n) 90 | { 91 | operator_unit(M, qs, i); 92 | } 93 | else 94 | { 95 | M = S; 96 | } 97 | 98 | qdpack_operator_list_append(&op_list, M); 99 | 100 | // XXX: free qs, free M 101 | } 102 | qdpack_operator_tensor(S, qs, &op_list); 103 | qdpack_operator_list_free_entries(&op_list); 104 | } 105 | 106 | return S; 107 | } 108 | 109 | /* 110 | * Calculate dS/dt at time t. 111 | * 112 | * Method: dS/dt = (S(t+h)-S(t-h))/(2h) 113 | */ 114 | qdpack_operator_t * 115 | basis_transform_derivative(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, int n, ho_w_func_t ho_w_cb, double t) 116 | { 117 | double h; 118 | qdpack_complex z; 119 | qdpack_operator_t *S1, *S2; 120 | 121 | h = 1e-6; 122 | S1 = basis_transform(sim, qs, n, ho_w_cb, t-h); 123 | S2 = basis_transform(sim, qs, n, ho_w_cb, t+h); 124 | 125 | qdpack_operator_sub(S2, S1); 126 | 127 | if (ho_w_cb(t, sim) < ho_w_cb(0.0, sim)) 128 | { 129 | QDPACK_SET_COMPLEX(&z, -1.0 / (2.0 * h), 0.0); 130 | } 131 | else 132 | { 133 | QDPACK_SET_COMPLEX(&z, 1.0 / (2.0 * h), 0.0); 134 | } 135 | 136 | qdpack_operator_scale(S2, z); 137 | 138 | qdpack_operator_free(S1); 139 | 140 | return S2; 141 | } 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /qdpack/qdpack_matrix_gsl.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // Description: 11 | // 12 | // A GSL based matrix backend for QDpack. 13 | // 14 | 15 | #ifndef _QDPACK_MATRIX 16 | #define _QDPACK_MATRIX 17 | 18 | #define GSL 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | // 30 | // complex number abstraction layer: map to GSL functions 31 | // 32 | 33 | #define qdpack_complex gsl_complex 34 | #define QDPACK_COMPLEX_ONE GSL_COMPLEX_ONE 35 | #define QDPACK_COMPLEX_NEGONE GSL_COMPLEX_NEGONE 36 | #define QDPACK_COMPLEX_ZERO GSL_COMPLEX_ZERO 37 | 38 | #define QDPACK_REAL GSL_REAL 39 | #define QDPACK_IMAG GSL_IMAG 40 | #define QDPACK_SET_COMPLEX GSL_SET_COMPLEX 41 | 42 | #define qdpack_complex_conjugate gsl_complex_conjugate 43 | 44 | #define qdpack_complex_mul gsl_complex_mul 45 | #define qdpack_complex_mul_real gsl_complex_mul_real 46 | #define qdpack_complex_div gsl_complex_div 47 | 48 | #define qdpack_complex_rect gsl_complex_rect 49 | #define qdpack_complex_polar gsl_complex_polar 50 | #define qdpack_complex_exp gsl_complex_exp 51 | 52 | #define qdpack_complex_add gsl_complex_add 53 | #define qdpack_complex_sub gsl_complex_sub 54 | 55 | #define qdpack_complex_abs gsl_complex_abs 56 | #define qdpack_complex_abs2 gsl_complex_abs2 57 | #define qdpack_complex_arg gsl_complex_arg 58 | 59 | #define qdpack_complex_negative gsl_complex_negative 60 | 61 | #define QDPACK_TRANSPOSE_t CBLAS_TRANSPOSE_t 62 | #define QDpackNoTrans CblasNoTrans 63 | #define QDpackTrans CblasTrans 64 | #define QDpackConjTrans CblasConjTrans 65 | 66 | // 67 | // matrix representation 68 | // 69 | typedef struct _qdpack_matrix { 70 | 71 | int n, m; 72 | 73 | gsl_matrix_complex *data; 74 | 75 | } qdpack_matrix_t; 76 | 77 | // matrix 78 | qdpack_matrix_t *qdpack_matrix_alloc(size_t m, size_t n); 79 | void qdpack_matrix_free(qdpack_matrix_t *mat); 80 | 81 | qdpack_complex qdpack_matrix_get(qdpack_matrix_t *mat, size_t i, size_t j); 82 | void qdpack_matrix_set(qdpack_matrix_t *mat, size_t i, size_t j, qdpack_complex value); 83 | void qdpack_matrix_set_all(qdpack_matrix_t *mat, qdpack_complex value); 84 | void qdpack_matrix_set_zero(qdpack_matrix_t *mat); 85 | void qdpack_matrix_set_identity(qdpack_matrix_t *mat); 86 | 87 | void qdpack_matrix_memcpy(qdpack_matrix_t *dst, qdpack_matrix_t *src); 88 | 89 | void qdpack_matrix_scale(qdpack_matrix_t *op, qdpack_complex z); 90 | void qdpack_matrix_add(qdpack_matrix_t *op1, qdpack_matrix_t *op2); 91 | void qdpack_matrix_sub(qdpack_matrix_t *op1, qdpack_matrix_t *op2); 92 | 93 | void qdpack_matrix_multiply(qdpack_matrix_t *A, qdpack_matrix_t *B, qdpack_matrix_t *C); 94 | 95 | void qdpack_matrix_blas_zgemm(QDPACK_TRANSPOSE_t transA, QDPACK_TRANSPOSE_t transB, 96 | qdpack_complex alpha, qdpack_matrix_t *A, qdpack_matrix_t *B, 97 | qdpack_complex beta, qdpack_matrix_t *C); 98 | 99 | qdpack_complex qdpack_matrix_multiply_vmv(qdpack_matrix_t *mat, qdpack_matrix_t *v); 100 | qdpack_complex qdpack_matrix_dot(qdpack_matrix_t *a, qdpack_matrix_t *b); // multiply_vv 101 | 102 | void qdpack_matrix_exp(qdpack_matrix_t *m, qdpack_matrix_t *exp_m); 103 | 104 | #define QDPACK_MATRIX_WRITE_FORMAT_REAL 0 105 | #define QDPACK_MATRIX_WRITE_FORMAT_IMAG 1 106 | #define QDPACK_MATRIX_WRITE_FORMAT_COMPLEX 2 107 | #define QDPACK_MATRIX_WRITE_FORMAT_PYTHON 3 108 | int qdpack_matrix_write(FILE *f, qdpack_matrix_t *m, int format); 109 | int qdpack_matrix_python_write(FILE *f, qdpack_matrix_t *M); 110 | 111 | 112 | // eigenstates 113 | #define QDPACK_EIGEN_SORT_VAL_ASC GSL_EIGEN_SORT_VAL_ASC 114 | #define QDPACK_EIGEN_SORT_PHASE GSL_EXT_EIGEN_SORT_PHASE 115 | 116 | int qdpack_matrix_eigen_hermv(qdpack_matrix_t *m, qdpack_matrix_t *eval, qdpack_matrix_t *evec, int sort_order); 117 | int qdpack_matrix_eigen_zgeev(qdpack_matrix_t *m, qdpack_matrix_t *eval, qdpack_matrix_t *evec, int sort_order); 118 | 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /qdpack/qdpack_matrix_cxsparse.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // Description: 11 | // 12 | // A GSL based matrix backend for QDpack. 13 | // 14 | 15 | #ifndef _QDPACK_MATRIX 16 | #define _QDPACK_MATRIX 17 | 18 | #include 19 | 20 | #include 21 | 22 | // 23 | // complex number abstraction layer: map to C99 complex type/functions 24 | // 25 | 26 | #define qdpack_complex double complex 27 | #define QDPACK_COMPLEX_ONE (1.0+0.0I) 28 | #define QDPACK_COMPLEX_NEGONE (-1.0+0.0I) 29 | #define QDPACK_COMPLEX_ZERO (0.0+0.0I) 30 | 31 | #define QDPACK_REAL(x) creal(x) 32 | #define QDPACK_IMAG(x) cimag(x) 33 | #define QDPACK_SET_COMPLEX(z,x,y) {*z=x+y*1.0I;} 34 | 35 | #define qdpack_complex_conjugate conj 36 | 37 | #define qdpack_complex_mul(a,b) (a*b) 38 | #define qdpack_complex_mul_real(a,b) (a*b) 39 | #define qdpack_complex_div(a,b) (a/b) 40 | 41 | #define qdpack_complex_rect(x,y) (x+y*1.0I) 42 | #define qdpack_complex_polar(r,theta) (r*cexp(theta)) 43 | #define qdpack_complex_exp cexp 44 | 45 | #define qdpack_complex_add(a,b) (a+b) 46 | #define qdpack_complex_sub(a,b) (a-b) 47 | 48 | #define qdpack_complex_abs cabs 49 | #define qdpack_complex_abs2(x) cpow(cabs(x),2) 50 | #define qdpack_complex_arg carg 51 | 52 | #define qdpack_complex_negative(x) (-x) 53 | 54 | #define QDPACK_TRANSPOSE_t int 55 | #define QDpackNoTrans 0 56 | #define QDpackTrans 1 57 | #define QDpackConjTrans 2 58 | 59 | // 60 | // matrix representation 61 | // 62 | typedef struct _qdpack_matrix { 63 | 64 | int n, m; 65 | 66 | // gsl_matrix_complex *data; 67 | 68 | cs_cl *data; 69 | 70 | } qdpack_matrix_t; 71 | 72 | // matrix 73 | qdpack_matrix_t *qdpack_matrix_alloc(size_t m, size_t n); 74 | void qdpack_matrix_free(qdpack_matrix_t *mat); 75 | 76 | qdpack_complex qdpack_matrix_get(qdpack_matrix_t *mat, size_t i, size_t j); 77 | void qdpack_matrix_set(qdpack_matrix_t *mat, size_t i, size_t j, qdpack_complex value); 78 | void qdpack_matrix_set_all(qdpack_matrix_t *mat, qdpack_complex value); 79 | void qdpack_matrix_set_zero(qdpack_matrix_t *mat); 80 | void qdpack_matrix_set_identity(qdpack_matrix_t *mat); 81 | 82 | void qdpack_matrix_memcpy(qdpack_matrix_t *dst, qdpack_matrix_t *src); 83 | 84 | void qdpack_matrix_scale(qdpack_matrix_t *op, qdpack_complex z); 85 | void qdpack_matrix_add(qdpack_matrix_t *op1, qdpack_matrix_t *op2); 86 | void qdpack_matrix_sub(qdpack_matrix_t *op1, qdpack_matrix_t *op2); 87 | 88 | void qdpack_matrix_multiply(qdpack_matrix_t *A, qdpack_matrix_t *B, qdpack_matrix_t *C); 89 | 90 | void qdpack_matrix_blas_zgemm(QDPACK_TRANSPOSE_t transA, QDPACK_TRANSPOSE_t transB, 91 | qdpack_complex alpha, qdpack_matrix_t *A, qdpack_matrix_t *B, 92 | qdpack_complex beta, qdpack_matrix_t *C); 93 | 94 | qdpack_complex qdpack_matrix_multiply_vmv(qdpack_matrix_t *mat, qdpack_matrix_t *v); 95 | qdpack_complex qdpack_matrix_dot(qdpack_matrix_t *a, qdpack_matrix_t *b); // multiply_vv 96 | 97 | #define QDPACK_MATRIX_WRITE_FORMAT_REAL 0 98 | #define QDPACK_MATRIX_WRITE_FORMAT_IMAG 1 99 | #define QDPACK_MATRIX_WRITE_FORMAT_COMPLEX 2 100 | #define QDPACK_MATRIX_WRITE_FORMAT_PYTHON 3 101 | int qdpack_matrix_write(FILE *f, qdpack_matrix_t *m, int format); 102 | int qdpack_matrix_sparse_write(FILE *f, qdpack_matrix_t *M, int format); 103 | int qdpack_matrix_python_write(FILE *f, qdpack_matrix_t *M); 104 | 105 | void qdpack_matrix_exp(qdpack_matrix_t *m, qdpack_matrix_t *exp_m); 106 | 107 | 108 | qdpack_complex * qdpack_vector_dense(qdpack_matrix_t *v); 109 | 110 | // 111 | void qdpack_matrix_triplet(qdpack_matrix_t *mat); 112 | void qdpack_matrix_compressed(qdpack_matrix_t *mat); 113 | 114 | // eigenstates 115 | #define QDPACK_EIGEN_SORT_VAL_ASC 0 116 | #define QDPACK_EIGEN_SORT_PHASE 1 117 | 118 | int qdpack_matrix_eigen_hermv(qdpack_matrix_t *m, qdpack_matrix_t *eval, qdpack_matrix_t *evec, int sort_order); 119 | int qdpack_matrix_eigen_zgeev(qdpack_matrix_t *m, qdpack_matrix_t *eval, qdpack_matrix_t *evec, int sort_order); 120 | 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /extra/qdpack-logo-v1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 24 | 26 | image/svg+xml 27 | 29 | 30 | 31 | 32 | 33 | 35 | 41 | 46 | 51 | 56 | 57 | 58 | 78 | QDpack 91 | Quantum dynamics 103 | 124 | -------------------------------------------------------------------------------- /qdpack/hilbert_space.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /* 10 | * Functions related to definition of quantum systems (composed of subsystems 11 | * with different sizes) and enummeration of states. 12 | * 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | /* ---------------------------------------------------------- 21 | * Index conversion functions: 22 | * 23 | */ 24 | 25 | /* 26 | * Calculate the superoperator index given two operator indices. 27 | * 28 | * J = N*a+b. 29 | */ 30 | int 31 | ss_idx_major(int N, int a, int b) 32 | { 33 | // printf("idx_major(%d, %d)[%d] = %d\n", a, b, N, N*a+b); 34 | return N*a + b; 35 | } 36 | 37 | /* 38 | * Calculate the first (most significant: ms) operator index 39 | * given one super-operator index (a). 40 | * 41 | * J = N*a + b, 42 | * Solve for a. 43 | */ 44 | int 45 | ss_idx_minor_ms(int N, int J) 46 | { 47 | return floor(((double)J)/N); // = a 48 | } 49 | 50 | /* 51 | * Calculate the second (least significant: ls) operator index 52 | * given one super-operator index (b). 53 | * 54 | * J = N*a + b, 55 | * Solve for b. 56 | */ 57 | int 58 | ss_idx_minor_ls(int N, int J) 59 | { 60 | return J - N * floor(((double)J)/N); // = b 61 | } 62 | 63 | /* ---------------------------------------------------------- 64 | * qdpack_hilbert_space_t object functions: 65 | * 66 | */ 67 | 68 | /** 69 | * Create a new qdpack_hilbert_space_t object. 70 | * 71 | */ 72 | qdpack_hilbert_space_t * 73 | qdpack_hilbert_space_new() 74 | { 75 | qdpack_hilbert_space_t *qs; 76 | 77 | if ((qs = malloc(sizeof(qdpack_hilbert_space_t))) == NULL) 78 | { 79 | fprintf(stderr, "Failed ot allocate a new qdpack_hilbert_space_t object\n"); 80 | return 0; 81 | } 82 | 83 | qs->nsubsys = 0; 84 | qs->nstates = NULL; 85 | 86 | return qs; 87 | } 88 | 89 | /* 90 | * Create a new qdpack_hilbert_space_t object using qs as a template. 91 | * 92 | * 93 | */ 94 | qdpack_hilbert_space_t * 95 | qdpack_hilbert_space_copy(qdpack_hilbert_space_t *qs) 96 | { 97 | int i; 98 | qdpack_hilbert_space_t *qs_new; 99 | 100 | qs_new = qdpack_hilbert_space_new(); 101 | for (i = 0; i < qs->nsubsys; i++) 102 | qdpack_hilbert_space_add(qs_new, qs->nstates[i]); 103 | 104 | return qs_new; 105 | } 106 | 107 | 108 | /* 109 | * 110 | * 111 | * 112 | */ 113 | void 114 | qdpack_hilbert_space_add(qdpack_hilbert_space_t *qs, int M) 115 | { 116 | int *nss, i; 117 | 118 | nss = malloc(sizeof(int) * (qs->nsubsys + 1)); 119 | 120 | for (i = 0; i < qs->nsubsys; i++) 121 | nss[i] = qs->nstates[i]; 122 | nss[qs->nsubsys] = M; 123 | qs->nsubsys = qs->nsubsys + 1; 124 | free(qs->nstates); 125 | qs->nstates = nss; 126 | } 127 | 128 | /* 129 | * 130 | * 131 | */ 132 | void 133 | qdpack_hilbert_space_print(qdpack_hilbert_space_t *qs) 134 | { 135 | int i; 136 | 137 | printf("Quantum system with %d sub systems: ", qs->nsubsys); 138 | for (i = 0; i < qs->nsubsys; i++) 139 | printf("%d ", qs->nstates[i]); 140 | printf("\n"); 141 | } 142 | 143 | /* 144 | * 145 | * 146 | */ 147 | void 148 | qdpack_hilbert_space_free(qdpack_hilbert_space_t *qs) 149 | { 150 | free(qs->nstates); 151 | free(qs); 152 | } 153 | 154 | 155 | 156 | /* 157 | * Calculate the number of quantum states in the full system. 158 | */ 159 | int 160 | qdpack_hilbert_space_nstates(qdpack_hilbert_space_t *qs) 161 | { 162 | int i, ns = 1; 163 | 164 | for (i = 0; i < qs->nsubsys; i++) 165 | { 166 | ns *= qs->nstates[i]; 167 | } 168 | 169 | return ns; 170 | } 171 | 172 | /* 173 | * Calculate the quantum state vector that correspond to the quantum 174 | * state number qsn. 175 | * 176 | */ 177 | void 178 | qdpack_hilbert_space_state_vector(qdpack_hilbert_space_t *qs, int qsn, qdpack_hilbert_space_state_vector_t qsv) 179 | { 180 | int i, acc; 181 | 182 | acc = qdpack_hilbert_space_nstates(qs); 183 | 184 | for (i = qs->nsubsys-1; i >= 0; i--) 185 | { 186 | acc = acc / qs->nstates[i]; 187 | qsv[i] = floor(qsn/acc); 188 | qsn -= qsv[i] * acc; 189 | } 190 | } 191 | 192 | /* 193 | * State vectors 194 | * 195 | */ 196 | int 197 | qdpack_hilbert_space_state_vector_print(qdpack_hilbert_space_t *qs, qdpack_hilbert_space_state_vector_t qsv) 198 | { 199 | int i; 200 | 201 | for (i = 0; i < qs->nsubsys; i++) 202 | printf("%d ", qsv[i]); 203 | 204 | return 0; 205 | } 206 | 207 | /* 208 | * Calculate the quantum state number that corresponds to the quantum 209 | * state vector qsv. 210 | */ 211 | int 212 | qdpack_hilbert_space_state_number(qdpack_hilbert_space_t *qs, qdpack_hilbert_space_state_vector_t qsv) 213 | { 214 | int qsn, i, acc_nqs; 215 | 216 | qsn = 0; 217 | acc_nqs = 1; 218 | 219 | for (i = 0; i < qs->nsubsys; i++) 220 | { 221 | qsn += acc_nqs * qsv[i]; 222 | acc_nqs *= qs->nstates[i]; 223 | } 224 | 225 | return qsn; 226 | } 227 | 228 | // 229 | // return a hilbert space that is a subspace of the given space 230 | // 231 | qdpack_hilbert_space_t * 232 | qdpack_hilbert_subspace_get(qdpack_hilbert_space_t *qs, int n) 233 | { 234 | qdpack_hilbert_space_t *subspace; 235 | 236 | if ((subspace = qdpack_hilbert_space_new()) == NULL) 237 | { 238 | // XXX: error message 239 | return NULL; 240 | } 241 | 242 | qdpack_hilbert_space_add(subspace, qs->nstates[n]); 243 | 244 | return subspace; 245 | } 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /examples/run_jc.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | // 11 | // Calculate the time evolution of a two-level system coupled to an oscillator 12 | // (Jaynes-Cumming model) 13 | // 14 | // $ mkdir -p data/jc 15 | // $ time ./run_jc 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | // Directory where all the data files are to be stored. 23 | #define DATADIR "data/jc/" 24 | 25 | // pointers to operators to calculate expectation values for 26 | static qdpack_operator_t *N_op[2]; 27 | 28 | // 29 | // Process the density matrix for time t: calculate expectation values for the 30 | // precomputed operators N_op[] 31 | // 32 | int 33 | rho_store_cb(qdpack_simulation_t *sp, 34 | qdpack_hilbert_space_t *qs, 35 | qdpack_operator_t *rho_t, double t) 36 | { 37 | qdpack_complex expt; 38 | char filename[1024], row[16384]; 39 | 40 | // qubit 41 | expt = qdpack_operator_expectation_value(rho_t, N_op[0]); 42 | snprintf(filename, sizeof(filename), "%s/qubit_excitation_prob_%s.dat", DATADIR, sp->simsig); 43 | snprintf(row, sizeof(row), "%f\t%f\t%f", t, QDPACK_REAL(expt), QDPACK_IMAG(expt)); 44 | qdpack_file_row_add(filename, row); 45 | 46 | // cavity 47 | expt = qdpack_operator_expectation_value(rho_t, N_op[1]); 48 | snprintf(filename, sizeof(filename), "%s/cavity_excitation_prob_%s.dat", DATADIR, sp->simsig); 49 | snprintf(row, sizeof(row), "%f\t%f\t%f", t, QDPACK_REAL(expt), QDPACK_IMAG(expt)); 50 | qdpack_file_row_add(filename, row); 51 | 52 | return 0; 53 | } 54 | 55 | 56 | // 57 | // Program starts here. 58 | // 59 | int 60 | main(int argc, char **argv) 61 | { 62 | qdpack_hilbert_space_t *qs; 63 | qdpack_operator_t *rho_q, *rho_c, *rho0; 64 | qdpack_operator_list_t dm_list; 65 | h_jc_parameters_t params; 66 | double Gamma_c, Gamma_q, Navg; 67 | 68 | // This data structure contains all the parameters needed by the solver. 69 | qdpack_simulation_t sim; 70 | qdpack_simulation_init(&sim); 71 | 72 | sim.parameters = (void *)¶ms; 73 | memset((void *)¶ms, 0, sizeof(h_jc_parameters_t)); 74 | 75 | // 76 | // Setup system (hamiltonian) parameter. 77 | // 78 | 79 | params.epsilon[0] = 1.0 * 2 * M_PI; // qubit energy splitting 80 | params.delta[0] = 0.0 * 2 * M_PI; // qubit tunnelling rate 81 | params.ho_w[0] = 1.0 * 2 * M_PI; // oscillator energy 82 | params.g_qc = 0.05 * 2 * M_PI; // coupling strength 83 | params.N = 50; // # fock states in the oscillator 84 | 85 | Gamma_c = 0.005; // cavity decay rate 86 | Gamma_q = 0.05; // qubit decay rate 87 | 88 | // 89 | // Setup solver parameters 90 | // 91 | sim.Ti = 0.0; 92 | sim.Tf = 25.0; 93 | sim.dT = sim.Tf / 100.0; 94 | 95 | // select a pre-defined hamiltonian for JC model 96 | sim.H0_func = (hamiltonian_func_t)hamiltonian_jc; 97 | 98 | // 99 | // create a new hilbert space object 100 | // 101 | qs = qdpack_hilbert_space_new(); 102 | qdpack_hilbert_space_add(qs, 2); 103 | qdpack_hilbert_space_add(qs, params.N); 104 | qdpack_hilbert_space_print(qs); 105 | 106 | // 107 | // create a "simulation signature" which is used in as a template for the 108 | // filenames for the output data 109 | // 110 | snprintf(sim.simsig, sizeof(sim.simsig), 111 | "Nq_%d_Nc_%d_wq_%.3f_who_%.3f_g_%.3f_Gq_%.3f_Gc_%.4f", 112 | qs->nstates[0], qs->nstates[1], 113 | sqrt(params.epsilon[0]*params.epsilon[0] + params.delta[0]*params.delta[0])/(2*M_PI), 114 | params.ho_w[0]/(2*M_PI), 115 | params.g_qc/(2*M_PI), Gamma_q, Gamma_c); 116 | 117 | // 118 | // Setup dissipation 119 | // 120 | Navg = 0; 121 | 122 | /* --- qubit --- */ 123 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 124 | operator_ho_lowering(sim.do_a[sim.do_n], qs, 0, 0); 125 | sim.do_g1[sim.do_n] = Gamma_q * (1 + Navg); // relaxation 126 | sim.do_g2[sim.do_n] = Gamma_q * Navg; // excitation 127 | sim.do_n++; 128 | 129 | /* --- cavity --- */ 130 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 131 | operator_ho_lowering(sim.do_a[sim.do_n], qs, 1, params.n_offset); 132 | sim.do_g1[sim.do_n] = Gamma_c * (1 + Navg); // relaxation 133 | sim.do_g2[sim.do_n] = Gamma_c * Navg; // excitation 134 | sim.do_n++; 135 | 136 | // 137 | // Pre-calc of operators to calculate expectation values for. 138 | // 139 | N_op[0] = qdpack_operator_alloc(qs); 140 | operator_ho_N(N_op[0], qs, 0, 0); 141 | N_op[1] = qdpack_operator_alloc(qs); 142 | operator_ho_N(N_op[1], qs, 1, params.n_offset); 143 | 144 | // 145 | // Setup initial state 146 | // 147 | rho_q = qdpack_dm_pure_TLS(1.0); 148 | rho_c = qdpack_dm_fock_state(0, qs->nstates[1]); 149 | 150 | // create a composite initial density matrix 151 | qdpack_operator_list_init(&dm_list); 152 | qdpack_operator_list_append(&dm_list, rho_q); 153 | qdpack_operator_list_append(&dm_list, rho_c); 154 | rho0 = qdpack_operator_alloc(qs); 155 | qdpack_operator_tensor(rho0, qs, &dm_list); 156 | 157 | // 158 | // Evolve the quantum system until time t = T 159 | // 160 | printf("Start evolving system\n"); 161 | if (qdpack_evolve_dm_lme(&sim, qs, rho0, rho_store_cb) != 0) 162 | { 163 | fprintf(stderr, "Evolution of the quantum system failed.\n"); 164 | return -1; 165 | } 166 | 167 | return 0; 168 | } 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /extra/qdpack-square-logo-v2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 24 | 26 | image/svg+xml 27 | 29 | 30 | 31 | 32 | 33 | 35 | 41 | 46 | 51 | 56 | 57 | 58 | 82 | QD 130 | pack 142 | 143 | -------------------------------------------------------------------------------- /examples/run_nTLS.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // Simulate the time evolution of a system of N two-level systems (TLS). 11 | // 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | 24 | /** 25 | * Process the density matrix for time t (calc. expectations values, 26 | * store to file, etc.). This is a callback function that the solver 27 | * call in each time-step. 28 | */ 29 | int 30 | rho_store_cb(qdpack_operator_t *rho_t, double t, qdpack_hilbert_space_t *qs, qdpack_simulation_t *sp) 31 | { 32 | double c; 33 | int i; 34 | char filename[128], row[512]; 35 | qdpack_operator_t *dm_part; 36 | 37 | for (i = 0; i < qs->nsubsys; i++) 38 | { 39 | snprintf(filename, sizeof(filename), "data.qubits/tls_%d_dynamics.dat", i); 40 | 41 | dm_part = qdpack_operator_traceout(qs, rho_t, i); 42 | 43 | snprintf(row, sizeof(row), "%f\t%f\t%f\t%f\t%f", t, 44 | QDPACK_REAL(qdpack_operator_get(dm_part, 0, 0)), 45 | QDPACK_REAL(qdpack_operator_get(dm_part, 0, 1)), 46 | QDPACK_REAL(qdpack_operator_get(dm_part, 1, 0)), 47 | QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1))); 48 | 49 | qdpack_file_row_add(filename, row); 50 | qdpack_operator_free(dm_part); 51 | } 52 | 53 | /* --- concurrence -- */ 54 | snprintf(filename, sizeof(filename), "data.qubits/concurrence.dat"); 55 | c = qdpack_dm_concurrence(qs, rho_t); 56 | snprintf(row, sizeof(row), "%f\t%f", t, c); 57 | qdpack_file_row_add(filename, row); 58 | 59 | return 0; 60 | } 61 | 62 | 63 | /* --- 64 | * Two-level system parameters: 65 | * 66 | * H = sum_i(-0.5 espilon[i] sigma_z(i) - 0.5 delta[i] sigma_x(i)) + sum_ij(- 0.5 lambda[i][j] sigma_x[i] sigma_x[j]) 67 | * 68 | */ 69 | double epsilon[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0}; 70 | double delta[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 71 | double *lambda[10]; 72 | 73 | 74 | /* --- 75 | * Program starts here. 76 | * 77 | */ 78 | int 79 | main(int argc, char **argv) 80 | { 81 | qdpack_hilbert_space_t *qs; 82 | qdpack_operator_t *rho1, *rho2; 83 | qdpack_operator_t *rho0; 84 | qdpack_operator_list_t dm_list; 85 | int qsn, i; 86 | 87 | qdpack_simulation_t param; 88 | qdpack_simulation_init(¶m); 89 | 90 | /* 91 | * Setup solver parameters. 92 | * 93 | */ 94 | 95 | // TLS hamiltonian parameters 96 | param.epsilon = epsilon; 97 | param.delta = delta; 98 | for (i = 0; i < 10; i++) 99 | { 100 | param.epsilon[i] *= 2*M_PI; 101 | param.delta[i] *= 2*M_PI; 102 | lambda[i] = (double *)calloc(10, sizeof(double)); 103 | } 104 | lambda[0][1] = 0.25 * 2*M_PI; 105 | lambda[1][2] = 0.4 * 2*M_PI; 106 | lambda[2][3] = 0.3 * 2*M_PI; 107 | lambda[3][4] = 0.2 * 2*M_PI; 108 | lambda[4][5] = 0.1 * 2*M_PI; 109 | param.lambda = lambda; 110 | 111 | 112 | // time range 113 | param.Ti = 0.0; 114 | param.Tf = 10.0; 115 | param.dT = 0.01; 116 | 117 | param.N = 6; 118 | 119 | // driving field (set to zero to disable) 120 | param.h_td_A = 0.0 * 2 * M_PI; 121 | param.h_td_w = 0.0 * 2 * M_PI; 122 | 123 | 124 | // function pointer to the functions generating the hamiltonian matrices 125 | param.H0_func = (hamiltonian_func_t)hamiltonian_qubits; 126 | param.H1_func = (hamiltonian_func_t)hamiltonian_drive; 127 | param.Ht_func = (hamiltonian_td_func_t)hamiltonian_t; 128 | 129 | /* 130 | * create a new quantum system object 131 | */ 132 | qs = qdpack_hilbert_space_new(); 133 | 134 | for (i = 0; i < param.N; i++) 135 | qdpack_hilbert_space_add(qs, 2); 136 | qsn = qdpack_hilbert_space_nstates(qs); 137 | qdpack_hilbert_space_print(qs); 138 | 139 | 140 | /* 141 | * Set up dissipation 142 | * 143 | */ 144 | param.do_n = 0; 145 | param.do_a[param.do_n] = operator_ho_lowering(qs, 0); // qubit 0 146 | param.do_g1[param.do_n] = 0.50; // relaxation 147 | param.do_g2[param.do_n] = 0.05; // excitation 148 | param.do_n++; 149 | param.do_a[param.do_n] = operator_ho_lowering(qs, 1); // qubit 1 150 | param.do_g1[param.do_n] = 0.25; // relaxation 151 | param.do_g2[param.do_n] = 0.01; // excitation 152 | param.do_n++; 153 | param.do_a[param.do_n] = operator_sigma_z(qs, 0); // qubit 0 154 | param.do_g1[param.do_n] = 0.25; // dephasing 155 | param.do_n++; 156 | 157 | 158 | /* 159 | * debug 160 | * 161 | */ 162 | printf("sigma_x(0) = \n"); qdpack_operator_print(operator_sigma_x(qs,0), 4); 163 | printf("sigma_x(0) = \n"); qdpack_operator_print(operator_sigma_x(qs,1), 4); 164 | printf("sigma_y(0) = \n"); qdpack_operator_print(operator_sigma_y(qs,0), 4); 165 | printf("sigma_y(0) = \n"); qdpack_operator_print(operator_sigma_y(qs,1), 4); 166 | 167 | 168 | /* 169 | * Setup initial state 170 | */ 171 | rho1 = qdpack_dm_pure_TLS(0.8); // 0.8|0>+0.2|1> 172 | rho2 = qdpack_dm_pure_TLS(0.3); // 0.3|0>+0.7|1> 173 | 174 | qdpack_operator_list_init(&dm_list); 175 | qdpack_operator_list_append(&dm_list, rho1); 176 | for (i = 1; i < param.N; i++) 177 | qdpack_operator_list_append(&dm_list, rho2); 178 | 179 | rho0 = qdpack_operator_tensor(qs, &dm_list); 180 | 181 | //printf("rho0 =\n"); 182 | //qdpack_operator_print(rho0, qsn); 183 | 184 | 185 | /* 186 | * Evolve the quantum system. 187 | * 188 | */ 189 | //if (qdpack_evolve_dm_lme_t(qs, rho0, ¶m, rho_store_cb) != 0) 190 | if (qdpack_evolve_dm_unitary_const(qs, rho0, ¶m, rho_store_cb) != 0) 191 | //if (qdpack_evolve_dm_unitary_t(qs, rho0, ¶m, rho_store_cb) != 0) 192 | { 193 | fprintf(stderr, "Evolution of the quantum system failed.\n"); 194 | return -1; 195 | } 196 | 197 | return 0; 198 | } 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /qdpack/hamiltonian.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | /** 10 | * @file hamiltonian.h 11 | * 12 | * @brief Functions for generating hamiltonians in matrix form. 13 | * 14 | * @author Robert Johansson 15 | * 16 | */ 17 | 18 | #ifndef HAMILTONIAN_H 19 | #define HAMILTONIAN_H 20 | 21 | #include 22 | 23 | #define H_MAX_TERMS 20 24 | 25 | //------------------------------------------------------------------------------ 26 | // Generic time-dependence 27 | //------------------------------------------------------------------------------ 28 | 29 | //typedef int(*hamiltonian_func_real_t)(qdpack_hilbert_space_t *qs, qdpack_simulation_t *sim, qdpack_operator_t *H); 30 | 31 | int hamiltonian_t(qdpack_simulation_t *sim, qdpack_operator_t *H_t, qdpack_operator_t *H0, qdpack_operator_t *H1, double t); 32 | 33 | //------------------------------------------------------------------------------ 34 | // coupled two-level systems 35 | //------------------------------------------------------------------------------ 36 | 37 | typedef struct { 38 | 39 | /* -- Hamiltonian -- */ 40 | int N; 41 | 42 | double epsilon[H_MAX_TERMS]; 43 | double delta[H_MAX_TERMS]; 44 | //double g_interaction[H_MAX_TERMS]; 45 | double lambda[H_MAX_TERMS][H_MAX_TERMS]; 46 | 47 | } h_qubits_parameters_t; 48 | 49 | int hamiltonian_qubits(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 50 | int hamiltonian_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 51 | int hamiltonian_z_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 52 | int hamiltonian_x_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 53 | 54 | int hamiltonian_spinchain(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 55 | 56 | //------------------------------------------------------------------------------ 57 | // coupled oscillators 58 | //------------------------------------------------------------------------------ 59 | 60 | typedef struct { 61 | 62 | int N, n_offset; 63 | 64 | double ho_w[H_MAX_TERMS]; 65 | double ho_g; 66 | double ho_g2; 67 | double ho_wd; 68 | double g_qc; 69 | double g_cr; 70 | 71 | double xi; 72 | 73 | } h_ho_parameters_t; 74 | 75 | int hamiltonian_2ho(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 76 | int hamiltonian_2ho_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 77 | 78 | int hamiltonian_2ho_optmech(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 79 | int hamiltonian_2ho_optmech_linearized(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 80 | int hamiltonian_2ho_cooling(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 81 | 82 | //------------------------------------------------------------------------------ 83 | // Jaynes-Cumming style hamiltonians (qubit coupled to oscillator mode) 84 | //------------------------------------------------------------------------------ 85 | 86 | typedef struct { 87 | 88 | int N, n_offset; 89 | 90 | double ho_w[H_MAX_TERMS]; 91 | double ho_g; 92 | double ho_g2; 93 | double ho_wd; 94 | double g_qc; 95 | double g_cr; 96 | 97 | double epsilon[H_MAX_TERMS]; 98 | double delta[H_MAX_TERMS]; 99 | 100 | } h_jc_parameters_t; 101 | 102 | int hamiltonian_jc(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 103 | int hamiltonian_jc_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 104 | 105 | int hamiltonian_q2ho(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 106 | int hamiltonian_q2ho_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 107 | 108 | int hamiltonian_3ls_ho(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 109 | int hamiltonian_3ls_ho_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 110 | 111 | int hamiltonian_ho(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 112 | int hamiltonian_ho_drive(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 113 | 114 | //------------------------------------------------------------------------------ 115 | // 116 | //------------------------------------------------------------------------------ 117 | 118 | typedef struct { 119 | 120 | double j; 121 | double *J_w; 122 | double g_ac, g_sc; 123 | 124 | int N, n_offset; 125 | 126 | double ho_w[H_MAX_TERMS]; 127 | double ho_g; 128 | double ho_g2; 129 | double ho_wd; 130 | double g_qc; 131 | double g_cr, g0, g1; 132 | 133 | //int N; 134 | 135 | double epsilon[H_MAX_TERMS]; 136 | double delta[H_MAX_TERMS]; 137 | double g_interaction[H_MAX_TERMS]; 138 | //double lambda[H_MAX_TERMS][H_MAX_TERMS]; 139 | 140 | } h_dicke_parameters_t; 141 | 142 | int hamiltonian_dicke(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 143 | 144 | int hamiltonian_2ls_largespin(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 145 | 146 | //------------------------------------------------------------------------------ 147 | // 148 | //------------------------------------------------------------------------------ 149 | int hamiltonian_squeezing(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 150 | 151 | //------------------------------------------------------------------------------ 152 | // 153 | //------------------------------------------------------------------------------ 154 | //int hamiltonian_jc(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 155 | 156 | //------------------------------------------------------------------------------ 157 | // multi-level quantum model 158 | //------------------------------------------------------------------------------ 159 | int hamiltonian_mls_qdot(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 160 | int hamiltonian_mls_qdot_largespin(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, qdpack_operator_t *H); 161 | 162 | #endif 163 | 164 | -------------------------------------------------------------------------------- /qdpack/gsl_ext_expm_complex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman, Brian Gough 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or (at 7 | * your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | /* Author: G. Jungman */ 20 | /* Author: R. Johansson */ 21 | 22 | /* Calculate the matrix exponential, following 23 | * Moler + Van Loan, SIAM Rev. 20, 801 (1978). 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include "gsl_ext_expm_complex.h" 36 | 37 | /* store one of the suggested choices for the 38 | * Taylor series / square method from Moler + VanLoan 39 | */ 40 | struct moler_vanloan_optimal_suggestion 41 | { 42 | int k; 43 | int j; 44 | }; 45 | typedef struct moler_vanloan_optimal_suggestion mvl_suggestion_t; 46 | 47 | 48 | /* table from Moler and Van Loan 49 | * mvl_tab[gsl_mode_t][matrix_norm_group] 50 | */ 51 | static mvl_suggestion_t mvl_tab[3][6] = 52 | { 53 | /* double precision */ 54 | { 55 | { 5, 1 }, { 5, 4 }, { 7, 5 }, { 9, 7 }, { 10, 10 }, { 8, 14 } 56 | }, 57 | 58 | /* single precision */ 59 | { 60 | { 2, 1 }, { 4, 0 }, { 7, 1 }, { 6, 5 }, { 5, 9 }, { 7, 11 } 61 | }, 62 | 63 | /* approx precision */ 64 | { 65 | { 1, 0 }, { 3, 0 }, { 5, 1 }, { 4, 5 }, { 4, 8 }, { 2, 11 } 66 | } 67 | }; 68 | 69 | 70 | inline 71 | static double 72 | sup_norm(const gsl_matrix_complex * A) 73 | { 74 | unsigned int i, j; 75 | double max = 0.0; 76 | 77 | for (i = 0; i < A->size1; i++) 78 | { 79 | for (j = 0; j < A->size2; j++) 80 | { 81 | gsl_complex z = gsl_matrix_complex_get(A, i, j); 82 | 83 | if (gsl_complex_abs(z) > max) 84 | max = gsl_complex_abs(z); 85 | } 86 | } 87 | 88 | return max; 89 | } 90 | 91 | 92 | static 93 | mvl_suggestion_t 94 | obtain_suggestion(const gsl_matrix_complex * A, gsl_mode_t mode) 95 | { 96 | const unsigned int mode_prec = GSL_MODE_PREC(mode); 97 | const double norm_A = sup_norm(A); 98 | if(norm_A < 0.01) return mvl_tab[mode_prec][0]; 99 | else if(norm_A < 0.1) return mvl_tab[mode_prec][1]; 100 | else if(norm_A < 1.0) return mvl_tab[mode_prec][2]; 101 | else if(norm_A < 10.0) return mvl_tab[mode_prec][3]; 102 | else if(norm_A < 100.0) return mvl_tab[mode_prec][4]; 103 | else if(norm_A < 1000.0) return mvl_tab[mode_prec][5]; 104 | else 105 | { 106 | /* outside the table we simply increase the number 107 | * of squarings, bringing the reduced matrix into 108 | * the range of the table; this is obviously suboptimal, 109 | * but that is the price paid for not having those extra 110 | * table entries 111 | */ 112 | const double extra = log(1.01*norm_A/1000.0) / M_LN2; 113 | const int extra_i = (unsigned int) ceil(extra); 114 | mvl_suggestion_t s = mvl_tab[mode][5]; 115 | s.j += extra_i; 116 | return s; 117 | } 118 | } 119 | 120 | 121 | /* use series representation to calculate matrix exponential; 122 | * this is used for small matrices; we use the sup_norm 123 | * to measure the size of the terms in the expansion 124 | */ 125 | static void 126 | matrix_complex_exp_series( 127 | const gsl_matrix_complex * B, 128 | gsl_matrix_complex * eB, 129 | int number_of_terms 130 | ) 131 | { 132 | int count; 133 | gsl_matrix_complex *temp = gsl_matrix_complex_calloc(B->size1, B->size2); 134 | gsl_complex z; 135 | gsl_complex alpha, beta; 136 | 137 | GSL_SET_COMPLEX(&alpha, 1.0, 0.0); 138 | GSL_SET_COMPLEX(&beta, 0.0, 0.0); 139 | 140 | /* init the Horner polynomial evaluation, 141 | * eB = 1 + B/number_of_terms; we use 142 | * eB to collect the partial results 143 | */ 144 | gsl_matrix_complex_memcpy(eB, B); 145 | GSL_SET_COMPLEX(&z, 1.0/number_of_terms, 0.0); 146 | gsl_matrix_complex_scale(eB, z); 147 | GSL_SET_COMPLEX(&z, 1.0, 0.0); 148 | gsl_matrix_complex_add_diagonal(eB, z); 149 | for(count = number_of_terms-1; count >= 1; --count) 150 | { 151 | /* mult_temp = 1 + B eB / count */ 152 | gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, alpha, B, eB, beta, temp); 153 | GSL_SET_COMPLEX(&z, 1.0/count, 0.0); 154 | gsl_matrix_complex_scale(temp, z); 155 | GSL_SET_COMPLEX(&z, 1.0, 0.0); 156 | gsl_matrix_complex_add_diagonal(temp, z); 157 | 158 | /* transfer partial result out of temp */ 159 | gsl_matrix_complex_memcpy(eB, temp); 160 | } 161 | 162 | /* now eB holds the full result; we're done */ 163 | gsl_matrix_complex_free(temp); 164 | } 165 | 166 | 167 | int 168 | gsl_linalg_complex_exponential_ss( 169 | const gsl_matrix_complex * A, 170 | gsl_matrix_complex * eA, 171 | gsl_mode_t mode 172 | ) 173 | { 174 | if(A->size1 != A->size2) 175 | { 176 | GSL_ERROR("cannot exponentiate a non-square matrix", GSL_ENOTSQR); 177 | } 178 | else if(A->size1 != eA->size1 || A->size2 != eA->size2) 179 | { 180 | GSL_ERROR("exponential of matrix must have same dimension as matrix", GSL_EBADLEN); 181 | } 182 | else 183 | { 184 | int i; 185 | const mvl_suggestion_t sugg = obtain_suggestion(A, mode); 186 | const double divisor = exp(M_LN2 * sugg.j); 187 | gsl_complex z_divisor; 188 | gsl_complex alpha, beta; 189 | 190 | gsl_matrix_complex * reduced_A = gsl_matrix_complex_alloc(A->size1, A->size2); 191 | 192 | GSL_SET_COMPLEX(&alpha, 1.0, 0.0); 193 | GSL_SET_COMPLEX(&beta, 0.0, 0.0); 194 | 195 | /* decrease A by the calculated divisor */ 196 | gsl_matrix_complex_memcpy(reduced_A, A); 197 | GSL_SET_COMPLEX(&z_divisor, 1.0/divisor, 0.0); 198 | gsl_matrix_complex_scale(reduced_A, z_divisor); 199 | 200 | /* calculate exp of reduced matrix; store in eA as temp */ 201 | matrix_complex_exp_series(reduced_A, eA, sugg.k); 202 | 203 | /* square repeatedly; use reduced_A for scratch */ 204 | for(i = 0; i < sugg.j; ++i) 205 | { 206 | gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, alpha, eA, eA, beta, reduced_A); 207 | gsl_matrix_complex_memcpy(eA, reduced_A); 208 | } 209 | 210 | gsl_matrix_complex_free(reduced_A); 211 | 212 | return GSL_SUCCESS; 213 | } 214 | } 215 | 216 | -------------------------------------------------------------------------------- /tests/test_matrix_backend_cxsparse.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | int 17 | main(int argc, char **argv) 18 | { 19 | int i, j, n = 4, k, K = 8; 20 | 21 | qdpack_complex z; 22 | 23 | qdpack_matrix_t *m1, *m2, *m3, *m4; 24 | qdpack_matrix_t *v1, *v2; 25 | 26 | srand(time(NULL)); 27 | 28 | m1 = qdpack_matrix_alloc(n,n); 29 | m2 = qdpack_matrix_alloc(n,n); 30 | m3 = qdpack_matrix_alloc(n,n); 31 | m4 = qdpack_matrix_alloc(n,n); 32 | 33 | v1 = qdpack_matrix_alloc(n,1); 34 | v2 = qdpack_matrix_alloc(n,1); 35 | 36 | for (i = 0; i < n; i++) 37 | { 38 | for (j = 0; j < n; j++) 39 | { 40 | QDPACK_SET_COMPLEX(&z, rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX)); 41 | qdpack_matrix_set(m1, i, j, z); 42 | } 43 | 44 | qdpack_matrix_set(v1, i, 0, qdpack_complex_rect(rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX))); 45 | } 46 | 47 | 48 | for (k = 0; k < K; k++) 49 | { 50 | qdpack_complex z; 51 | 52 | i = rand() % n; 53 | j = rand() % n; 54 | 55 | QDPACK_SET_COMPLEX(&z, rand() / (0.1 * RAND_MAX), rand() / (0.1 * RAND_MAX)); 56 | qdpack_matrix_set(m2, i, j, z); 57 | } 58 | 59 | printf("\nm1 = \n"); 60 | qdpack_matrix_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 61 | 62 | printf("\nm2 = \n"); 63 | qdpack_matrix_write(stdout, m2, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 64 | 65 | printf("\nv1 = \n"); 66 | qdpack_matrix_write(stdout, v1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 67 | 68 | // 69 | // matrix multiplication 70 | // 71 | printf("\n\n========== matrix-matrix multiplication ==========\n\n"); 72 | 73 | qdpack_matrix_multiply(m1, m2, m3); 74 | 75 | printf("\nm3 = m1 * m2\n"); 76 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 77 | 78 | // 79 | // matrix-vector multiplication 80 | // 81 | printf("\n\n========== matrix-vector multiplication ==========\n\n"); 82 | 83 | qdpack_matrix_multiply(m1, v1, v2); 84 | 85 | printf("\nv2 = m1 * v1\n"); 86 | qdpack_matrix_write(stdout, v2, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 87 | 88 | // 89 | // vector-matrix-vector multiplication 90 | // 91 | printf("\n\n========== vector-matrix-vector multiplication ==========\n\n"); 92 | 93 | z = qdpack_matrix_multiply_vmv(m1, v1); 94 | printf("\nv1.H * m1 * v1 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 95 | 96 | z = qdpack_matrix_multiply_vmv(m2, v1); 97 | printf("\nv1.H * m2 * v1 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 98 | 99 | 100 | // 101 | // vector-vector multiplication 102 | // 103 | printf("\n\n========== vector-vector multiplication ==========\n\n"); 104 | 105 | z = qdpack_matrix_dot(v1, v1); 106 | printf("\nv1.H * v1 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 107 | 108 | z = qdpack_matrix_dot(v2, v2); 109 | printf("\nv2.H * v2 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 110 | 111 | z = qdpack_matrix_dot(v1, v2); 112 | printf("\nv1.H * v2 = (%.6e, %.6e)\n", QDPACK_REAL(z), QDPACK_IMAG(z)); 113 | 114 | 115 | // 116 | // matrix/vector set/get 117 | // 118 | printf("\n\n========== matrix/vector set/get ==========\n\n"); 119 | 120 | printf("\nm3 =\n"); 121 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 122 | 123 | qdpack_matrix_set_all(m3, QDPACK_COMPLEX_ONE); 124 | 125 | printf("\nm3 =\n"); 126 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 127 | 128 | qdpack_matrix_set_zero(m3); 129 | 130 | printf("\nm3 =\n"); 131 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 132 | 133 | // 134 | // matrix/vector copy 135 | // 136 | printf("\n\n========== matrix/vector copy ==========\n\n"); 137 | 138 | printf("\nm3 =\n"); 139 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 140 | 141 | printf("\nm2 =\n"); 142 | qdpack_matrix_write(stdout, m2, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 143 | 144 | qdpack_matrix_memcpy(m3, m2); 145 | 146 | printf("\nm3 =\n"); 147 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 148 | 149 | 150 | // 151 | // matrix/vector substraction 152 | // 153 | printf("\n\n========== matrix/vector sub ==========\n\n"); 154 | 155 | 156 | qdpack_matrix_sub(m3, m2); 157 | 158 | printf("\nm3 =\n"); 159 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 160 | qdpack_matrix_sparse_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 161 | qdpack_matrix_triplet(m3); 162 | qdpack_matrix_sparse_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_COMPLEX); 163 | 164 | // 165 | // matrix/vector add 166 | // 167 | printf("\n\n========== matrix/vector add ==========\n\n"); 168 | 169 | 170 | qdpack_matrix_add(m3, m2); 171 | 172 | printf("\nm3 =\n"); 173 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 174 | 175 | qdpack_matrix_add(m3, m2); 176 | 177 | printf("\nm3 =\n"); 178 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 179 | 180 | 181 | // 182 | // matrix-matrix blas multiplication 183 | // 184 | printf("\n\n========== matrix-matrix blas multiplication ==========\n\n"); 185 | 186 | printf("\nm1 = \n"); 187 | qdpack_matrix_write(stdout, m1, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 188 | 189 | printf("\nm2 = \n"); 190 | qdpack_matrix_write(stdout, m2, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 191 | 192 | qdpack_matrix_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, m1, m2, QDPACK_COMPLEX_ZERO, m3); 193 | 194 | printf("\nm3 = m1 * m2\n"); 195 | qdpack_matrix_write(stdout, m3, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 196 | 197 | qdpack_matrix_multiply(m1, m2, m4); 198 | 199 | printf("\nm4 = m1 * m2\n"); 200 | qdpack_matrix_write(stdout, m4, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 201 | 202 | qdpack_matrix_sub(m4, m3); 203 | 204 | printf("\nm4 - m3 =\n"); 205 | qdpack_matrix_write(stdout, m4, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 206 | 207 | qdpack_matrix_multiply(m1, m2, m4); 208 | 209 | qdpack_matrix_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, m1, m2, -QDPACK_COMPLEX_ONE, m4); 210 | 211 | printf("\nm1 * m2 - m1 * m2\n"); 212 | qdpack_matrix_write(stdout, m4, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 213 | 214 | qdpack_matrix_multiply(m1, m2, m4); 215 | 216 | qdpack_matrix_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, m1, m2, -2*QDPACK_COMPLEX_ONE, m4); 217 | 218 | printf("\nm1 * m2 - 2 * (m1 * m2)\n"); 219 | qdpack_matrix_write(stdout, m4, QDPACK_MATRIX_WRITE_FORMAT_PYTHON); 220 | 221 | return 0; 222 | } 223 | -------------------------------------------------------------------------------- /extra/qdpack-square-logo-v1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 24 | 26 | image/svg+xml 27 | 29 | 30 | 31 | 32 | 33 | 35 | 41 | 46 | 51 | 56 | 57 | 58 | 82 | QD 97 | package 142 | QD 157 | pack 169 | 170 | -------------------------------------------------------------------------------- /examples/run_2ls_driven_pss.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // The steady-state of a 2LS subject to a strong driving field: Find the steady 11 | // state by finding the eigenstates of the propagator. 12 | // 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #define DATADIR "data/2ls.pss" 26 | 27 | static double x, y; 28 | static qdpack_operator_t *rho_eb_t, *rho_tmp_t; 29 | 30 | /** 31 | * Strong driving hamiltonian : H_t = H0 + f(t) H1, f(t) = A * sin(w * t) 32 | * 33 | */ 34 | int 35 | hamiltonian_sd_t(qdpack_simulation_t *p, 36 | qdpack_operator_t *H_t, 37 | qdpack_operator_t *H0, 38 | qdpack_operator_t *H1, 39 | double t) 40 | { 41 | if (p->h_td_A == 0.0) 42 | { 43 | qdpack_operator_memcpy(H_t, H0); 44 | } 45 | else 46 | { 47 | qdpack_operator_memcpy(H_t, H1); 48 | qdpack_operator_scale(H_t, qdpack_complex_rect(p->h_td_A * sin(p->h_td_w * t) / 2, 0.0)); 49 | qdpack_operator_add(H_t, H0); 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | // 56 | // Process the density matrix for time t=T_final 57 | // 58 | int 59 | process_rho_final(qdpack_simulation_t *sim, 60 | qdpack_hilbert_space_t *qs, 61 | qdpack_operator_t *rho_cb_t, 62 | double t) 63 | { 64 | char filename[128], row[1024]; 65 | 66 | // 67 | // calculate the instantaneous eigenbasis 68 | // 69 | sim->Ht_func(sim, sim->H_t, sim->H0, sim->H1, sim->Tf); 70 | 71 | qdpack_matrix_eigen_hermv(sim->H_t->data, sim->eval, sim->evec->data, QDPACK_EIGEN_SORT_VAL_ASC); 72 | 73 | qdpack_operator_blas_zgemm(QDpackConjTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, sim->evec, rho_cb_t, QDPACK_COMPLEX_ZERO, rho_tmp_t); 74 | qdpack_operator_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, rho_tmp_t, sim->evec, QDPACK_COMPLEX_ZERO, rho_eb_t); 75 | 76 | // 77 | // store the qubit excitation probability in both charge basis (rho_cb_t) 78 | // and eigenbasis (rho_eb_t) 79 | // 80 | snprintf(filename, sizeof(filename), "%s/p_e_%s.dat", DATADIR, sim->simsig); 81 | snprintf(row, sizeof(row), "%f\t%f\t%f\t%f", 82 | x, y, 83 | QDPACK_REAL(qdpack_operator_get(rho_cb_t, 1, 1)), 84 | QDPACK_REAL(qdpack_operator_get(rho_eb_t, 1, 1))); 85 | 86 | qdpack_file_row_add(filename, row); 87 | 88 | return 0; 89 | } 90 | 91 | // 92 | // Program starts here. 93 | // 94 | int 95 | main(int argc, char **argv) 96 | { 97 | qdpack_hilbert_space_t *qs, *qs2; 98 | qdpack_operator_t *rho_ss, *U; 99 | int qsn; 100 | double Navg, fw, delta, G1, G2; 101 | double xi, xf, xd, yi, yf, yd; 102 | 103 | h_qubits_parameters_t qubit_params; 104 | 105 | // This data structure store all the parameters needed by the solver. 106 | qdpack_simulation_t sim; 107 | qdpack_simulation_init(&sim); 108 | 109 | sim.parameters = (void *)&qubit_params; 110 | memset((void *)&qubit_params, 0, sizeof(h_qubits_parameters_t)); 111 | 112 | if (argc != 7) 113 | { 114 | printf("usage: %s x-init x-step x-final y-init y-step y-final\n", argv[0]); 115 | printf("\nexammple: $ %s -10.0 0.2 10.0 0.0 0.1 10.0\n", argv[0]); 116 | exit(0); 117 | } 118 | 119 | // 120 | // parameters 121 | // 122 | 123 | xi = strtod(argv[1], NULL); 124 | xd = strtod(argv[2], NULL); 125 | xf = strtod(argv[3], NULL); 126 | 127 | yi = strtod(argv[4], NULL); 128 | yd = strtod(argv[5], NULL); 129 | yf = strtod(argv[6], NULL); 130 | 131 | fw = 2.0; // driving frequency 132 | delta = 0.1; // coefficient of sigma_x in qubit hamiltonian 133 | Navg = 0; // zero temperature 134 | 135 | G1 = 0.00001; 136 | G2 = 0.001; 137 | 138 | // 139 | // hamiltonian 140 | // 141 | sim.H0_func = (hamiltonian_func_t)hamiltonian_qubits; 142 | sim.H1_func = (hamiltonian_func_t)hamiltonian_z_drive; 143 | sim.Ht_func = (hamiltonian_td_func_t)hamiltonian_sd_t; 144 | 145 | // 146 | // create a hilbert space 147 | // 148 | qs = qdpack_hilbert_space_new(); 149 | qdpack_hilbert_space_add(qs, 2); // a 2-level system 150 | qsn = qdpack_hilbert_space_nstates(qs); 151 | 152 | qs2 = qdpack_hilbert_space_new(); 153 | qdpack_hilbert_space_add(qs2, 4); // a 2-level system 154 | 155 | // 156 | // Set up dissipation 157 | // 158 | 159 | // relaxation 160 | if (G1 > 0.0) 161 | { 162 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 163 | operator_ho_lowering(sim.do_a[sim.do_n], qs, 0, 0); 164 | sim.do_g1[sim.do_n] = G1 * (1 + Navg); // relaxation 165 | sim.do_g2[sim.do_n] = G1 * Navg; // excitation 166 | sim.do_n++; 167 | } 168 | 169 | // dephasing 170 | if (G2 > 0.0) 171 | { 172 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 173 | operator_sigma_z(sim.do_a[sim.do_n], qs, 0); 174 | sim.do_g1[sim.do_n] = G2 / 2; 175 | sim.do_g2[sim.do_n] = G2 / 2; 176 | sim.do_n++; 177 | } 178 | 179 | // output data file name signature 180 | snprintf(sim.simsig, sizeof(sim.simsig), "dDelta_%.3f_G1_%.6f_G2_%.4f_fw_%.3f", delta, G1, G2, fw); 181 | 182 | // 183 | // pre-allocate memory 184 | // 185 | sim.eval = qdpack_matrix_alloc(qsn, 1); 186 | sim.evec = qdpack_operator_alloc(qs); 187 | U = qdpack_operator_alloc(qs2); 188 | rho_eb_t = qdpack_operator_alloc(qs); 189 | rho_tmp_t = qdpack_operator_alloc(qs); 190 | rho_ss = qdpack_operator_alloc(qs); 191 | 192 | // 193 | // start sweep of parameter range 194 | // 195 | qubit_params.delta[0] = delta * 2 * M_PI; // qubit parameter: sigma_x coefficient 196 | sim.h_td_w = fw * 2 * M_PI; // driving frequency 197 | 198 | for (x = xi; x <= xf; x += xd) 199 | { 200 | qubit_params.epsilon[0] = x * (2*M_PI); // qubit parameter: sigma_z coefficient 201 | 202 | printf("ITERATION: %s: x = %f, y = %.2f:%.2f:%.2f\n", sim.simsig, x, yi, yd, yf); 203 | 204 | for (y = yi; y <= yf; y += yd) 205 | { 206 | sim.h_td_A = y * 2 * M_PI; // driving amplitude 207 | 208 | // calculate propagator for one period 209 | sim.Ti = 0.0; sim.Tf = 1/fw; sim.dT = 1/fw; 210 | if (qdpack_propagator_dm(&sim, qs, U, NULL) == -1) 211 | { 212 | fprintf(stderr, "Evaluation of the propagator failed.\n"); 213 | return -1; 214 | } 215 | 216 | // Find the steady state from the evolution operator 217 | if (qdpack_steadystate_dm_propagator(&sim, qs, U, rho_ss) == -1) 218 | { 219 | fprintf(stderr, "Evaluation of the propagator failed.\n"); 220 | return -1; 221 | } 222 | 223 | process_rho_final(&sim, qs, rho_ss, sim.Tf); 224 | } 225 | } 226 | 227 | return 0; 228 | } 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /qdpack/entanglement.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | /** 22 | * \breif Calculate the von Neumann Entropy of a system with density matrix rho. 23 | * 24 | * This function takes a density matrix as input and calculates the von Neumann entropy. 25 | * Note that the density matrix is not restricted to be representing any particular 26 | * for of quantum system. 27 | * 28 | * @param rho The density matrix for which the von Neumann entropy is to be calculated. 29 | * 30 | */ 31 | double 32 | qdpack_entanglement_neumann_entropy(qdpack_operator_t *rho) 33 | { 34 | int i; 35 | double e, ne = 0.0; 36 | qdpack_matrix_t *rho_w; 37 | qdpack_matrix_t *eval, *evec; 38 | 39 | rho_w = qdpack_matrix_alloc(rho->m, rho->n); 40 | qdpack_matrix_memcpy(rho_w, rho->data); 41 | 42 | eval = qdpack_matrix_alloc(rho->m, 1); 43 | evec = qdpack_matrix_alloc(rho->m, rho->n); 44 | 45 | qdpack_matrix_eigen_hermv(rho_w, eval, evec, 0); 46 | 47 | for (i = 0; i < rho->m; i++) 48 | { 49 | e = QDPACK_REAL(qdpack_matrix_get(eval, i, 0)); 50 | //ne += - e * log2(e); 51 | ne += - e * log(e); 52 | } 53 | 54 | /* clean-up */ 55 | qdpack_matrix_free(rho_w); 56 | qdpack_matrix_free(eval); 57 | qdpack_matrix_free(evec); 58 | 59 | return ne; 60 | } 61 | 62 | /** 63 | * \breif Calculate the log negativity for the density matrix of two TLS, rho. 64 | * 65 | * Calculate the negativity of a two-qubit system. 66 | * 67 | * @param rho Density matrix for a two-qubit system. 68 | * 69 | */ 70 | double 71 | qdpack_entanglement_log_neg(qdpack_operator_t *rho) 72 | { 73 | int i; 74 | double ln, sum_eval; 75 | qdpack_matrix_t *rho_pt; 76 | 77 | qdpack_matrix_t *eval, *evec; 78 | 79 | /* -- calculate partial transpose of rho, and store in rho_pt 80 | * 81 | * | x x A B | | x x a b | 82 | * | x x C D | -> | x x c d | 83 | * | a b y y | | A B y y | 84 | * | c d y y | | C D y y | 85 | * 86 | */ 87 | rho_pt = qdpack_matrix_alloc(4,4); 88 | qdpack_matrix_memcpy(rho_pt, rho->data); 89 | // A,B,C,D -> a,b,c,d 90 | qdpack_matrix_set(rho_pt, 0, 2, qdpack_operator_get(rho, 2, 0)); 91 | qdpack_matrix_set(rho_pt, 0, 3, qdpack_operator_get(rho, 2, 1)); 92 | qdpack_matrix_set(rho_pt, 1, 2, qdpack_operator_get(rho, 3, 0)); 93 | qdpack_matrix_set(rho_pt, 1, 3, qdpack_operator_get(rho, 3, 1)); 94 | // a,b,c,d -> A,B,C,D 95 | qdpack_matrix_set(rho_pt, 2, 0, qdpack_operator_get(rho, 0, 2)); 96 | qdpack_matrix_set(rho_pt, 2, 1, qdpack_operator_get(rho, 0, 3)); 97 | qdpack_matrix_set(rho_pt, 3, 0, qdpack_operator_get(rho, 1, 2)); 98 | qdpack_matrix_set(rho_pt, 3, 1, qdpack_operator_get(rho, 1, 3)); 99 | 100 | /* --- diagonalize rho_pt --- */ 101 | eval = qdpack_matrix_alloc(4, 1); 102 | evec = qdpack_matrix_alloc(4, 4); 103 | 104 | qdpack_matrix_eigen_hermv(rho_pt, eval, evec, 0); 105 | 106 | /* --- calculate the log negativity --- */ 107 | sum_eval = 0; 108 | for (i = 0; i < 4; i++) 109 | { 110 | sum_eval += qdpack_complex_abs(qdpack_matrix_get(eval, i, 0)); 111 | } 112 | ln = log2(sum_eval); 113 | 114 | /* clean-up */ 115 | qdpack_matrix_free(rho_pt); 116 | qdpack_matrix_free(eval); 117 | qdpack_matrix_free(evec); 118 | 119 | return ln; 120 | } 121 | 122 | 123 | /** 124 | * \breif Calculate the concurrence for the density matrix (two TLS) rho. 125 | * 126 | * Calculate the concurrence for the density matrix of a two-qubit system. 127 | * 128 | * @param qs Data structure that specifies the form of the quantum system. 129 | * @param rho The density matrix for a two-qubit system. 130 | * 131 | */ 132 | double 133 | qdpack_entanglement_concurrence(qdpack_hilbert_space_t *qs, qdpack_operator_t *rho) 134 | { 135 | double c = 0.0; 136 | qdpack_operator_t *y1, *y2, *y, *ws1, *ws2; 137 | qdpack_matrix_t *eval = qdpack_matrix_alloc(4, 1); 138 | qdpack_matrix_t *evec = qdpack_matrix_alloc(4, 4); 139 | 140 | y1 = qdpack_operator_alloc(qs); 141 | y2 = qdpack_operator_alloc(qs); 142 | 143 | operator_sigma_y(y1, qs, 0); 144 | operator_sigma_y(y2, qs, 1); 145 | 146 | y = qdpack_operator_alloc(qs); 147 | ws1 = qdpack_operator_alloc(qs); 148 | ws2 = qdpack_operator_alloc(qs); 149 | 150 | 151 | // calculate: rho * (y1 * y2) * rho' * (y1 * y2) 152 | // rho * y * rho' * y 153 | // --------------- ----------------- 154 | // ws1 ws2 155 | // 156 | qdpack_operator_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, y1, y2, QDPACK_COMPLEX_ZERO, y); 157 | 158 | qdpack_operator_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, rho, y, QDPACK_COMPLEX_ZERO, ws1); 159 | qdpack_operator_blas_zgemm(QDpackConjTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, rho, y, QDPACK_COMPLEX_ZERO, ws2); 160 | 161 | qdpack_operator_blas_zgemm(QDpackNoTrans, QDpackNoTrans, QDPACK_COMPLEX_ONE, ws1, ws2, QDPACK_COMPLEX_ZERO, y); 162 | 163 | //printf("rr_real = \n"); qdpack_operator_print_real(y); 164 | //printf("rr_imag = \n"); qdpack_operator_print_imag(y); 165 | printf("rr = \n"); qdpack_operator_print(y); 166 | 167 | // calculate eigenvalues 168 | qdpack_matrix_eigen_zgeev(y->data, eval, evec, 0); 169 | 170 | { 171 | int i, j, n = 4; 172 | 173 | printf("Eigenvalues = \n"); 174 | for (i = 0; i < n; i++) 175 | { 176 | qdpack_complex z; 177 | z = qdpack_matrix_get(eval, i, 0); 178 | printf("\t(%f, %f)", QDPACK_REAL(z), QDPACK_IMAG(z)); 179 | } 180 | printf("\n"); 181 | 182 | printf("evec = \n"); 183 | for (i = 0; i < n; i++) 184 | { 185 | for (j = 0; j < n; j++) 186 | { 187 | qdpack_complex z; 188 | z = qdpack_matrix_get(evec, i, j); 189 | printf("\t(%f, %f)", QDPACK_REAL(z), QDPACK_IMAG(z)); 190 | } 191 | printf("\n"); 192 | } 193 | } 194 | 195 | printf("c: eigvals: (%f, %f), (%f, %f), (%f, %f), (%f, %f)\n", 196 | QDPACK_REAL(qdpack_matrix_get(eval, 0, 0)), QDPACK_IMAG(qdpack_matrix_get(eval, 0, 0)), 197 | QDPACK_REAL(qdpack_matrix_get(eval, 1, 0)), QDPACK_IMAG(qdpack_matrix_get(eval, 1, 0)), 198 | QDPACK_REAL(qdpack_matrix_get(eval, 2, 0)), QDPACK_IMAG(qdpack_matrix_get(eval, 2, 0)), 199 | QDPACK_REAL(qdpack_matrix_get(eval, 3, 0)), QDPACK_IMAG(qdpack_matrix_get(eval, 3, 0))); 200 | 201 | c = + QDPACK_REAL(qdpack_matrix_get(eval, 0, 0)) - QDPACK_REAL(qdpack_matrix_get(eval, 1, 0)) 202 | - QDPACK_REAL(qdpack_matrix_get(eval, 2, 0)) - QDPACK_REAL(qdpack_matrix_get(eval, 3, 0)); 203 | 204 | c = (c < 0.0) ? 0.0 : c; 205 | 206 | qdpack_operator_free(y1); 207 | qdpack_operator_free(y2); 208 | qdpack_operator_free(y); 209 | qdpack_operator_free(ws1); 210 | qdpack_operator_free(ws2); 211 | qdpack_matrix_free(evec); 212 | qdpack_matrix_free(eval); 213 | 214 | return c; 215 | } 216 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /examples/run_spinchain.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | // 11 | // calculate the dynamics of a spin-1/2 chain 12 | // 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | /** 20 | * Directory where all the data files are to be stored, 21 | * relative to the directory from which the program is 22 | * started. 23 | */ 24 | #define DATADIR "data/spinchain/" 25 | 26 | static qdpack_operator_t *N_op[10]; // XXX 27 | 28 | /* --- 29 | * Process the density matrix for time t (calc. expectations values, 30 | * store to file, etc.) 31 | */ 32 | int 33 | rho_store_cb(qdpack_simulation_t *sim, qdpack_hilbert_space_t *qs, 34 | qdpack_operator_t *rho_t, double t) 35 | { 36 | double ent_ln, ent_ln_sum = 0.0, ent_ne, ent_ne_sum = 0.0; 37 | int i, j, row1_offset, row2_offset; 38 | char filename1[128], filename2[128], row1[4096], row2[4096]; 39 | qdpack_operator_t *dm_part; 40 | qdpack_hilbert_space_t *qs_mask; 41 | 42 | 43 | // 44 | // calculate entanglement between qubits 45 | // 46 | 47 | qs_mask = qdpack_hilbert_space_copy(qs); 48 | for (i = 0; i < qs_mask->nsubsys; i++) 49 | { 50 | qs_mask->nstates[i] = 1; 51 | } 52 | 53 | snprintf(filename1, sizeof(filename1), "%s/ent_int_pairwise_%s.dat", DATADIR, sim->simsig); 54 | snprintf(filename2, sizeof(filename2), "%s/ent_ext_pairwise_%s.dat", DATADIR, sim->simsig); 55 | row1_offset = snprintf(row1, sizeof(row1), "%f", t); 56 | row2_offset = snprintf(row2, sizeof(row2), "%f", t); 57 | 58 | for (i = 0; i < qs->nsubsys-1; i++) 59 | { 60 | qs_mask->nstates[i] = 0; 61 | for (j = i+1; j < qs->nsubsys; j++) 62 | { 63 | qs_mask->nstates[j] = 0; 64 | 65 | dm_part = qdpack_operator_traceout_multi(qs, rho_t, qs_mask); 66 | ent_ln = qdpack_entanglement_log_neg(dm_part); 67 | ent_ln_sum += ent_ln; 68 | row1_offset += snprintf(&row1[row1_offset], sizeof(row1)-row1_offset, "\t%f", ent_ln); 69 | ent_ne = qdpack_entanglement_neumann_entropy(dm_part); 70 | ent_ne_sum += ent_ne; 71 | row2_offset += snprintf(&row2[row2_offset], sizeof(row2)-row2_offset, "\t%f", ent_ne); 72 | 73 | qdpack_operator_free(dm_part); 74 | qs_mask->nstates[j] = 1; 75 | } 76 | qs_mask->nstates[i] = 1; 77 | } 78 | 79 | snprintf(&row1[row1_offset], sizeof(row1)-row1_offset, "\t%f", ent_ln_sum); 80 | qdpack_file_row_add(filename1, row1); 81 | snprintf(&row2[row1_offset], sizeof(row2)-row2_offset, "\t%f", ent_ln_sum); 82 | qdpack_file_row_add(filename2, row2); 83 | 84 | /* --- expectation values -- */ 85 | 86 | for (i = 0; i < ((h_qubits_parameters_t *)sim->parameters)->N; i++) 87 | { 88 | qdpack_complex expt; 89 | 90 | expt = qdpack_operator_expectation_value(rho_t, N_op[i]); 91 | snprintf(filename1, sizeof(filename1), "%s/qubit_occupation_%d_%s.dat", DATADIR, i, sim->simsig); 92 | snprintf(row1, sizeof(row1), "%f\t%f\t%f", t, QDPACK_REAL(expt), QDPACK_IMAG(expt)); 93 | qdpack_file_row_add(filename1, row1); 94 | } 95 | 96 | return 0; 97 | } 98 | 99 | /* 100 | * 101 | * 102 | */ 103 | int 104 | main(int argc, char **argv) 105 | { 106 | qdpack_hilbert_space_t *qs; 107 | qdpack_operator_t *rho1, *rho2; 108 | qdpack_operator_t *rho0; 109 | qdpack_operator_list_t dm_list; 110 | int i; 111 | double G1, Navg; 112 | 113 | h_qubits_parameters_t qubit_params; 114 | 115 | // This data structure store all the parameters needed by the solver. 116 | qdpack_simulation_t sim; 117 | qdpack_simulation_init(&sim); 118 | 119 | sim.parameters = (void *)&qubit_params; 120 | memset((void *)&qubit_params, 0, sizeof(h_qubits_parameters_t)); 121 | 122 | /* 123 | * Setup solver parameters. 124 | * 125 | */ 126 | 127 | qubit_params.N = 6; 128 | 129 | /* TLS hamiltonian parameters, i.e. 130 | * 131 | * - energy splitting: qubit_params.epsilon[i] 132 | * - tunneling energy: qubit_params.delta[i] 133 | * - inter-qubit coupling: qubit_params.lambda[i][j] 134 | * 135 | * where i and j is two qubit indices. The actual numerical 136 | * values are defined in the arrays above. 137 | */ 138 | 139 | for (i = 0; i < qubit_params.N; i++) 140 | { 141 | qubit_params.epsilon[i] = 1.0 * 2*M_PI; 142 | qubit_params.delta[i] = 0.0 * 2*M_PI; 143 | } 144 | 145 | for (i = 0; i < qubit_params.N-1; i++) 146 | { 147 | qubit_params.lambda[i][i+1] = 0.05 * 2*M_PI; 148 | } 149 | 150 | 151 | // Configure the time range for the evolution: 152 | // - Ti = initial time 153 | // - Tf = final time 154 | // - dT = time-step between each call to the rho_store 155 | // callback function. The solver itself uses 156 | // an adaptive step length for accuracy control. 157 | // 158 | sim.Ti = 0.0; 159 | sim.Tf = 50.0; 160 | sim.dT = 0.01; 161 | 162 | // Select the pre-defined coupled-qubit hamiltonian 163 | // 164 | sim.H0_func = (hamiltonian_func_t)hamiltonian_qubits; 165 | 166 | // Create a new quantum system object: Here we configure 167 | // the quantum systems that make up the total system. We 168 | // call qdpack_hilbert_space_add for each subsystem, and the 169 | // second simeter defines how many quantum state that 170 | // subsystem has. 171 | // 172 | qs = qdpack_hilbert_space_new(); 173 | for (i = 0; i < qubit_params.N; i++) 174 | qdpack_hilbert_space_add(qs, 2); 175 | qdpack_hilbert_space_print(qs); 176 | 177 | // 178 | // Simulation signature to be used in file name for output data files 179 | // 180 | snprintf(sim.simsig, sizeof(sim.simsig), "N_%d", qubit_params.N); 181 | 182 | // 183 | // Set up dissipation 184 | // 185 | // 186 | G1 = 0.01; 187 | for (i = 0; i < qubit_params.N; i++) 188 | { 189 | Navg = 0.0; 190 | 191 | if (G1 > 0.0) 192 | { 193 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 194 | operator_ho_lowering(sim.do_a[sim.do_n], qs, i, 0); 195 | sim.do_g1[sim.do_n] = (Navg + 1) * G1; // relaxation rate 196 | sim.do_g2[sim.do_n] = Navg * G1; // excitation rate 197 | sim.do_n++; 198 | } 199 | } 200 | 201 | // 202 | // Setup initial state 203 | // 204 | rho1 = qdpack_dm_pure_TLS(1.0); 205 | rho2 = qdpack_dm_pure_TLS(0.0); 206 | 207 | qdpack_operator_list_init(&dm_list); 208 | qdpack_operator_list_append(&dm_list, rho1); 209 | for (i = 1; i < qubit_params.N; i++) 210 | qdpack_operator_list_append(&dm_list, rho2); 211 | 212 | rho0 = qdpack_operator_alloc(qs); 213 | qdpack_operator_tensor(rho0, qs, &dm_list); 214 | 215 | // 216 | // pre-calculate operators for expectation values 217 | // 218 | for (i = 0; i < qubit_params.N; i++) 219 | { 220 | N_op[i] = qdpack_operator_alloc(qs); 221 | //operator_ho_N(N_op[i], qs, i, 0); // number operator for qubit i 222 | operator_sigma_x(N_op[i], qs, i); 223 | } 224 | 225 | printf("starting time evolution... \n"); 226 | 227 | // 228 | // Evolve the quantum system. 229 | // 230 | if (qdpack_evolve_dm_lme(&sim, qs, rho0, rho_store_cb) != 0) 231 | //if (qdpack_evolve_dm_lme_t(qs, rho0, ¶m, rho_store_cb) != 0) 232 | //if (qdpack_evolve_dm_unitary_const(qs, rho0, ¶m, rho_store_cb) != 0) 233 | //if (qdpack_evolve_dm_unitary_t(qs, rho0, ¶m, rho_store_cb) != 0) 234 | { 235 | fprintf(stderr, "Evolution of the quantum system failed.\n"); 236 | return -1; 237 | } 238 | 239 | return 0; 240 | } 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /examples/run_qubits.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, J Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // Simulate the time evolution of a system of N two-level systems (TLS). 11 | // 12 | // $ mkdir -p data/qubit.dynamics 13 | // $ 14 | // 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | /** 22 | * Directory where all the data files are to be stored, 23 | * relative to the directory from which the program is 24 | * started. 25 | */ 26 | #define DATADIR "data/qubit.dynamics/" 27 | 28 | /** 29 | * Process the density matrix for time t (calc. expectations values, 30 | * store to file, etc.). This is a callback function that the solver 31 | * call in each time-step. 32 | * 33 | * Here we can calculate expectation values etc. In this case we only 34 | * do simple ... 35 | */ 36 | int 37 | rho_store_cb(qdpack_simulation_t *sp, qdpack_hilbert_space_t *qs, 38 | qdpack_operator_t *rho_t, double t) 39 | { 40 | int i; 41 | char filename[128], row[512]; 42 | qdpack_operator_t *dm_part; 43 | 44 | for (i = 0; i < qs->nsubsys; i++) 45 | { 46 | /* 47 | * For each subsystem's density matrix, extract the diagonal elements 48 | * that is the qubits occupation probabilities, and store to data 49 | * files. 50 | */ 51 | dm_part = qdpack_operator_traceout(qs, rho_t, i); 52 | 53 | snprintf(filename, sizeof(filename), "%s/qubit_population_%d.dat", DATADIR, i); 54 | snprintf(row, sizeof(row), "%f\t%f\t%f", t, 55 | QDPACK_REAL(qdpack_operator_get(dm_part, 0, 0)), // rho^{qubit i}_{0,0} 56 | QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1))); // rho^{qubit i}_{1,1} 57 | 58 | qdpack_file_row_add(filename, row); 59 | 60 | qdpack_operator_free(dm_part); 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | /** 67 | * Program starts here: Set up and start a calculation that simulates 68 | * the time-evolution of a coupled qubits. 69 | */ 70 | int 71 | main(int argc, char **argv) 72 | { 73 | qdpack_hilbert_space_t *qs; 74 | qdpack_operator_t *rho1, *rho2; 75 | qdpack_operator_t *rho0; 76 | qdpack_operator_list_t dm_list; 77 | int i; 78 | 79 | h_qubits_parameters_t qubit_params; 80 | 81 | // This data structure store all the parameters needed by the solver. 82 | qdpack_simulation_t sim; 83 | qdpack_simulation_init(&sim); 84 | 85 | sim.parameters = (void *)&qubit_params; 86 | memset((void *)&qubit_params, 0, sizeof(h_qubits_parameters_t)); 87 | 88 | /* 89 | * Setup solver parameters: 90 | * 91 | * Which simeters in qdpack_simulation_t that are used depends 92 | * on which hamiltonian generating function that is used 93 | * later on. Here we will use the hamiltonian for coupled 94 | * two-level systems, so we configure the following simeters 95 | * accordingly: 96 | * 97 | */ 98 | 99 | /* Number of two-level systems (qubits) */ 100 | qubit_params.N = 2; 101 | 102 | /* TLS hamiltonian parameters, i.e. 103 | * 104 | * - energy splitting: qubit_params.epsilon[i] 105 | * - tunneling energy: qubit_params.delta[i] 106 | * - inter-qubit coupling: qubit_params.lambda[i][j] 107 | * 108 | * where i and j is two qubit indices. The actual numerical 109 | * values are defined in the arrays above. 110 | */ 111 | 112 | 113 | qubit_params.epsilon[0] = 1.0 * 2*M_PI; 114 | qubit_params.delta[0] = 0.0 * 2*M_PI; 115 | 116 | qubit_params.epsilon[1] = 1.0 * 2*M_PI; 117 | qubit_params.delta[1] = 0.0 * 2*M_PI; 118 | 119 | /* qubits are coupled in a chain */ 120 | qubit_params.lambda[0][1] = 0.100 * 2*M_PI; 121 | qubit_params.lambda[1][2] = 0.050 * 2*M_PI; 122 | 123 | 124 | /* Configure the time range for the evolution: 125 | * - Ti = initial time 126 | * - Tf = final time 127 | * - dT = time-step between each call to the rho_store 128 | * callback function. The solver itself uses 129 | * an adaptive step length for accuracy control. 130 | */ 131 | sim.Ti = 0.0; 132 | sim.Tf = 20.0; 133 | sim.dT = 0.01; 134 | 135 | /* 136 | * If we want to apply a driving field to the qubits (i.e. 137 | * for dynamic coupling, rabi oscillations, etc.), the following 138 | * two variables define the amplitude and frequency of the 139 | * driving field. The operator that the driving field couple 140 | * to is defined by the hamiltonian_drive function, see below. 141 | * 142 | * Set the amplitude h_td_A to zero to disable driving. 143 | */ 144 | sim.h_td_A = 1.5 * 2 * M_PI; 145 | sim.h_td_w = 10.0 * 2 * M_PI; 146 | 147 | 148 | /* Function pointers to the functions that generate the Hamiltonian 149 | * matrices. Ht_func is called by the solver and expected to return 150 | * the instantanous value of the Hamiltonian (at time t). This function 151 | * can be customized for each simulation, but often it is sufficient 152 | * to use the standard from: 153 | * 154 | * H(t) = H_0 + H_1 * h_td_A * cos(h_td_w * t) 155 | * 156 | * which is implemented by the function hamiltonian_t from the 157 | * QDpack's library of standard Hamiltonians. 158 | * 159 | */ 160 | sim.H0_func = (hamiltonian_func_t)hamiltonian_qubits; 161 | sim.H1_func = (hamiltonian_func_t)hamiltonian_drive; 162 | sim.Ht_func = (hamiltonian_td_func_t)hamiltonian_t; 163 | 164 | 165 | /* Create a new quantum system object: Here we configure 166 | * the quantum systems that make up the total system. We 167 | * call qdpack_hilbert_space_add for each subsystem, and the 168 | * second simeter defines how many quantum state that 169 | * subsystem has. 170 | * 171 | */ 172 | qs = qdpack_hilbert_space_new(); 173 | for (i = 0; i < qubit_params.N; i++) 174 | qdpack_hilbert_space_add(qs, 2); 175 | qdpack_hilbert_space_print(qs); 176 | 177 | 178 | /* 179 | * Set up dissipation: Here we can define operators and rates 180 | * that appear in the master equation (relaxation rate, dephasing 181 | * rates, etc.) for each subsystem. 182 | * 183 | */ 184 | sim.do_n = 0; 185 | 186 | // QUBIT 0: 187 | // no dissipation 188 | 189 | // QUBIT 1: 190 | // Relaxation 191 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 192 | operator_ho_lowering(sim.do_a[sim.do_n], qs, 1, 0); // qubit 1 193 | sim.do_g1[sim.do_n] = 0.075; // relaxation rate 194 | sim.do_g2[sim.do_n] = 0.00; // excitation rate (zero temperature) 195 | sim.do_n++; 196 | 197 | // Pure dephasing 198 | //sim.do_a[sim.do_n] = qdpack_operator_alloc(qs) 199 | // operator_sigma_z(sim.do_a[sim.do_n], qs, 1, 0); // qubit 1 200 | // sim.do_g1[sim.do_n] = 0.25; // dephasing rate 201 | // sim.do_n++; 202 | 203 | // QUBIT 2: 204 | // Relaxation 205 | sim.do_a[sim.do_n] = qdpack_operator_alloc(qs); 206 | operator_ho_lowering(sim.do_a[sim.do_n] , qs, 2, 0); // qubit 2 207 | sim.do_g1[sim.do_n] = 0.25; // relaxation rate 208 | sim.do_g2[sim.do_n] = 0.05; // excitation rate 209 | sim.do_n++; 210 | 211 | 212 | /* 213 | * Setup initial state: Here we set the initial state for all qubits 214 | * to its ground state. 215 | */ 216 | rho1 = qdpack_dm_pure_TLS(1.0); // = density matrix that correspond to |psi> = 1.0 |0> + 0.0 |1> 217 | rho2 = qdpack_dm_pure_TLS(0.0); // = density matrix that correspond to |psi> = 1.0 |0> + 0.0 |1> 218 | 219 | qdpack_operator_list_init(&dm_list); 220 | qdpack_operator_list_append(&dm_list, rho1); 221 | for (i = 1; i < qubit_params.N; i++) 222 | qdpack_operator_list_append(&dm_list, rho2); 223 | 224 | rho0 = qdpack_operator_alloc(qs); 225 | qdpack_operator_tensor(rho0, qs, &dm_list); 226 | 227 | printf("rho0 =\n"); 228 | qdpack_operator_print(rho0); 229 | 230 | 231 | /* 232 | * Evolve the quantum system: We can use different solvers 233 | * for different kind of evolution. Here we use the LME solver 234 | * (Lindblad Master Equation). 235 | * 236 | * The solver will call the callback function "rho_store_cb" for 237 | * each time-step. In the callback function we can calculate 238 | * expectation values, etc., and store to files. 239 | * 240 | */ 241 | if (qdpack_evolve_dm_lme(&sim, qs, rho0, rho_store_cb) != 0) // dissipative evolution: Lindblad Master Equation 242 | //if (qdpack_evolve_dm_unitary_const(&sim, qs, rho0, rho_store_cb) != 0) // unitary evolution with constant Hamiltonian 243 | //if (qdpack_evolve_dm_unitary_t(&sim, qs, rho0, rho_store_cb) != 0) // unitary evolution with time-dependent Hamiltonian 244 | { 245 | fprintf(stderr, "Evolution of the quantum system failed.\n"); 246 | return -1; 247 | } 248 | 249 | return 0; 250 | } 251 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /examples/run_adiabatic.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | // 10 | // Simulate an adiabatic quantum computation. 11 | // 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | 25 | #define DATADIR "data/adiabatic" 26 | 27 | /* --- 28 | * This function defines the time-dependence of the hamiltonian. 29 | * 30 | */ 31 | int 32 | hamiltonian_sweep_t(qdpack_operator_t *H_t, qdpack_operator_t *H0, qdpack_operator_t *H1, double t, qdpack_simulation_t *p) 33 | { 34 | double lambda = t; 35 | qdpack_complex z; 36 | 37 | /* 38 | * H(t) = (lambda - 1) H0 + lambda H1 39 | */ 40 | 41 | if (lambda == 0.0) 42 | { 43 | qdpack_operator_memcpy(H_t, H0); 44 | } 45 | else 46 | { 47 | /* 48 | * First calculate: H = (lambda-1)/lambda H0 49 | */ 50 | qdpack_operator_memcpy(H_t, H0); 51 | QDPACK_SET_COMPLEX(&z, (1.0 - lambda)/lambda, 0.0); 52 | qdpack_operator_scale(H_t, z); 53 | 54 | /* 55 | * Next, add H1: H = (lambda-1)/lambda H0 + H1 56 | */ 57 | qdpack_operator_add(H_t, H1); 58 | 59 | /* 60 | * Finally, multiply with lambda: 61 | * 62 | * H = lambda ((1 - lambda)/lambda H0 + H1) = (1 - lambda) H0 + lambda H1 = H(t) 63 | */ 64 | QDPACK_SET_COMPLEX(&z, lambda, 0.0); 65 | qdpack_operator_scale(H_t, z); 66 | } 67 | 68 | /* 69 | * Diagonalize the hamiltonian and save eigenvalues to file: 70 | */ 71 | { 72 | qdpack_operator_t *M, *evec; 73 | gsl_vector *eval; 74 | gsl_eigen_hermv_workspace *w; 75 | char filename[256], row[1024]; 76 | int qsn, ri, j; 77 | 78 | qsn = qdpack_hilbert_space_nstates(p->qs); 79 | M = qdpack_operator_alloc(qsn, qsn); 80 | evec = qdpack_operator_alloc(qsn, qsn); 81 | eval = gsl_vector_alloc(qsn); 82 | w = gsl_eigen_hermv_alloc(qsn); 83 | 84 | qdpack_operator_memcpy(M, H_t); 85 | gsl_eigen_hermv(M, eval, evec, w); 86 | gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC); 87 | 88 | ri = 0; 89 | snprintf(filename, sizeof(filename), "%s/H_evals%s.dat", DATADIR, p->simsig); 90 | ri = snprintf(row, sizeof(row), "%f", t); 91 | for (j = 0; j < qsn; j++) 92 | { 93 | ri += snprintf(&row[ri], sizeof(row)-ri, "\t%f", gsl_vector_get(eval, j)); 94 | } 95 | qdpack_file_row_add(filename, row); 96 | 97 | gsl_vector_free(eval); 98 | qdpack_operator_free(M); 99 | qdpack_operator_free(evec); 100 | 101 | } 102 | 103 | return 0; 104 | } 105 | 106 | /* 107 | * Reverse sigma_z coefficients in qubits hamiltonian 108 | * 109 | */ 110 | qdpack_operator_t * 111 | hamiltonian_qubits_reverse(qdpack_hilbert_space_t *qs, qdpack_simulation_t *param) 112 | { 113 | int i; 114 | qdpack_operator_t *H; 115 | 116 | /* reverse sigma_z coefficients */ 117 | for (i = 0; i < 10; i++) 118 | param->epsilon[i] *= -1.0; 119 | 120 | H = hamiltonian_qubits(qs, param); 121 | 122 | /* restore sigma_z coefficients */ 123 | for (i = 0; i < 10; i++) 124 | param->epsilon[i] *= -1.0; 125 | 126 | return H; 127 | } 128 | 129 | /** 130 | * Process the density matrix for time t (calc. expectations values, 131 | * store to file, etc.). This is a callback function that the solver 132 | * call in each time-step. 133 | */ 134 | int 135 | rho_store_cb(qdpack_operator_t *rho_t, double t, qdpack_hilbert_space_t *qs, qdpack_simulation_t *sp) 136 | { 137 | double c; 138 | int i; 139 | char filename[256], row[512]; 140 | qdpack_operator_t *dm_part; 141 | 142 | for (i = 0; i < qs->nsubsys; i++) 143 | { 144 | snprintf(filename, sizeof(filename), "%s/tls_%d_dynamics%s.dat", DATADIR, i, sp->simsig); 145 | 146 | dm_part = qdpack_operator_traceout(qs, rho_t, i); 147 | 148 | snprintf(row, sizeof(row), "%f\t%f\t%f\t%f\t%f", t, 149 | QDPACK_REAL(qdpack_operator_get(dm_part, 0, 0)), 150 | QDPACK_REAL(qdpack_operator_get(dm_part, 0, 1)), 151 | QDPACK_REAL(qdpack_operator_get(dm_part, 1, 0)), 152 | QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1))); 153 | 154 | qdpack_file_row_add(filename, row); 155 | qdpack_operator_free(dm_part); 156 | } 157 | 158 | return 0; 159 | } 160 | 161 | 162 | /* --- 163 | * Two-level system parameters: 164 | * 165 | * H = sum_i(-0.5 espilon[i] sigma_z(i) - 0.5 delta[i] sigma_x(i)) + sum_ij(- 0.5 lambda[i][j] sigma_x[i] sigma_x[j]) 166 | * 167 | */ 168 | double epsilon[] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; 169 | double delta[] = {100.0, 100.0, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1}; 170 | double *lambda[10]; 171 | 172 | 173 | /* --- 174 | * Program starts here. 175 | * 176 | */ 177 | int 178 | main(int argc, char **argv) 179 | { 180 | qdpack_hilbert_space_t *qs; 181 | qdpack_operator_t *rho1; 182 | qdpack_operator_t *rho0; 183 | qdpack_operator_list_t dm_list; 184 | int qsn, i; 185 | double Tf; 186 | 187 | qdpack_simulation_t param; 188 | qdpack_simulation_init(¶m); 189 | 190 | /* 191 | * Setup solver parameters. 192 | * 193 | */ 194 | 195 | Tf = 30 * delta[0] / epsilon[0]; 196 | 197 | // TLS hamiltonian parameters 198 | param.epsilon = epsilon; 199 | param.delta = delta; 200 | for (i = 0; i < 10; i++) 201 | { 202 | param.delta[i] *= 2*M_PI; 203 | param.epsilon[i] *= 2*M_PI * Tf; 204 | lambda[i] = (double *)calloc(10, sizeof(double)); 205 | } 206 | lambda[0][1] = 0.2 * 2*M_PI; 207 | lambda[1][2] = 0.2 * 2*M_PI; 208 | lambda[2][3] = 0.2 * 2*M_PI; 209 | lambda[3][4] = 0.2 * 2*M_PI; 210 | lambda[4][5] = 0.2 * 2*M_PI; 211 | param.lambda = lambda; 212 | 213 | 214 | // time range 215 | param.Ti = 0.0; 216 | param.Tf = 1.0; 217 | param.dT = 0.005; 218 | 219 | param.N = 2; 220 | 221 | // driving field (set to zero to disable) 222 | param.h_td_A = 0.0 * 2 * M_PI; 223 | param.h_td_w = 0.0 * 2 * M_PI; 224 | 225 | 226 | // function pointer to the functions generating the hamiltonian matrices 227 | param.H0_func = (hamiltonian_func_t)hamiltonian_qubits; 228 | param.H1_func = (hamiltonian_func_t)hamiltonian_qubits_reverse; 229 | param.Ht_func = (hamiltonian_td_func_t)hamiltonian_sweep_t; 230 | 231 | /* 232 | * create a new quantum system object 233 | */ 234 | qs = qdpack_hilbert_space_new(); 235 | 236 | for (i = 0; i < param.N; i++) 237 | qdpack_hilbert_space_add(qs, 2); 238 | qsn = qdpack_hilbert_space_nstates(qs); 239 | qdpack_hilbert_space_print(qs); 240 | param.qs = qs; 241 | 242 | /* 243 | * Set up dissipation 244 | * 245 | * / 246 | param.do_n = 0; 247 | param.do_a[param.do_n] = operator_ho_lowering(qs, 0); // qubit 0 248 | param.do_g1[param.do_n] = 0.50; // relaxation 249 | param.do_g2[param.do_n] = 0.05; // excitation 250 | param.do_n++; 251 | param.do_a[param.do_n] = operator_ho_lowering(qs, 1); // qubit 1 252 | param.do_g1[param.do_n] = 0.25; // relaxation 253 | param.do_g2[param.do_n] = 0.01; // excitation 254 | param.do_n++; 255 | param.do_a[param.do_n] = operator_sigma_z(qs, 0); // qubit 0 256 | param.do_g1[param.do_n] = 0.25; // dephasing 257 | param.do_n++; 258 | */ 259 | 260 | /* 261 | * Setup initial state 262 | */ 263 | rho1 = qdpack_dm_pure_TLS(0.0); // 0.8|0>+0.2|1> 264 | 265 | qdpack_operator_list_init(&dm_list); 266 | qdpack_operator_list_append(&dm_list, rho1); 267 | for (i = 1; i < param.N; i++) 268 | qdpack_operator_list_append(&dm_list, rho1); 269 | 270 | rho0 = qdpack_operator_tensor(qs, &dm_list); 271 | 272 | //printf("rho0 =\n"); 273 | //qdpack_operator_print(rho0, qsn); 274 | 275 | /* 276 | * Create a simulation signature that will be appended as 277 | * an identifier on all output file names. 278 | */ 279 | snprintf(param.simsig, sizeof(param.simsig), "_N_%d_V_%.3f_Delta_%.3f", param.N, param.epsilon[0] / (2*M_PI), param.delta[0] / (2*M_PI)); 280 | 281 | /* 282 | * Evolve the quantum system. 283 | * 284 | */ 285 | //if (qdpack_evolve_dm_lme_t(qs, rho0, ¶m, rho_store_cb) != 0) 286 | //if (qdpack_evolve_dm_unitary_const(qs, rho0, ¶m, rho_store_cb) != 0) 287 | if (qdpack_evolve_dm_unitary_t(qs, rho0, ¶m, rho_store_cb) != 0) 288 | { 289 | fprintf(stderr, "Evolution of the quantum system failed.\n"); 290 | return -1; 291 | } 292 | 293 | return 0; 294 | } 295 | 296 | 297 | 298 | -------------------------------------------------------------------------------- /examples/run_qubit_tls.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | static char DATADIR[256]; 21 | static double pe_0_expt_sum = 0.0, pe_0_max = 0.0; 22 | static int pe_0_expt_no = 0; 23 | static double pe_1_expt_sum = 0.0; 24 | static int pe_1_expt_no = 0; 25 | #define DATADIR_TEMPLATE "/home/rob/qdpack-data/%s" 26 | 27 | /** 28 | * Strong driving hamiltonian 29 | * 30 | */ 31 | int 32 | hamiltonian_qubit_t(qdpack_operator_t *H_t, qdpack_operator_t *H0, qdpack_operator_t *H1, double t, qdpack_simulation_t *p) 33 | { 34 | if (p->h_td_A == 0.0) 35 | { 36 | qdpack_operator_memcpy(H_t, H0); 37 | // p->H_t = p->H_0; 38 | } 39 | else 40 | { 41 | qdpack_complex z; 42 | 43 | // H_t = H0 + f(t) H1 44 | // f(t) = A * sin(w * t) 45 | 46 | //qdpack_operator_memcpy(H_t, H0); 47 | qdpack_operator_memcpy(H_t, H1); 48 | QDPACK_SET_COMPLEX(&z, p->h_td_A * cos(p->h_td_w * t) / 2, 0.0); 49 | qdpack_operator_scale(H_t, z); 50 | qdpack_operator_add(H_t, H0); 51 | } 52 | 53 | return 0; 54 | } 55 | 56 | 57 | /* --- 58 | * Process the density matrix for time t (calc. expectations values, 59 | * store to file, etc.) 60 | */ 61 | int 62 | rho_store_final_cb(qdpack_operator_t *rho_t, double t, qdpack_hilbert_space_t *qs, qdpack_simulation_t *sp) 63 | { 64 | qdpack_complex N_expt; 65 | char filename[128], row[1024]; 66 | 67 | snprintf(filename, sizeof(filename), "%s/p_e%s.dat", DATADIR, sp->simsig); 68 | 69 | /* -- expectation values -- */ 70 | snprintf(row, sizeof(row), "%f\t%f\t%f\t%f\t%f\t%f", sp->x, sp->y, sp->epsilon[0]/(2*M_PI), 71 | pe_0_expt_sum / pe_0_expt_no, pe_0_max, pe_1_expt_sum / pe_1_expt_no); 72 | qdpack_file_row_add(filename, row); 73 | 74 | return 0; 75 | } 76 | 77 | /* --- 78 | * Process the density matrix for time t (calc. expectations values, 79 | * store to file, etc.) 80 | */ 81 | int 82 | rho_store_cb(qdpack_operator_t *rho_t, double t, qdpack_hilbert_space_t *qs, qdpack_simulation_t *sp) 83 | { 84 | int i, j, ri; 85 | qdpack_complex N_expt, op1_expt, op2_expt; 86 | char filename[1024], row[16384]; 87 | qdpack_operator_t *dm_part; //, *op; 88 | 89 | /* 90 | * For each sub-system: 91 | * 92 | */ 93 | for (i = 0; i < qs->nsubsys; i++) 94 | { 95 | ri = 0; 96 | 97 | //printf("Procssing subsystem [%d] at time %f\n", i, t); 98 | 99 | //snprintf(filename, sizeof(filename), "%s/rho_%d_diag%s_x_%.3f_y_%.3f.dat", DATADIR, i, sp->simsig, sp->x, sp->y); 100 | 101 | dm_part = qdpack_operator_traceout(qs, rho_t, i); 102 | 103 | //ri = snprintf(row, sizeof(row), "%f", t); 104 | // 105 | //for (j = 0; j < qs->nstates[i]; j++) 106 | //{ 107 | // ri += snprintf(&row[ri], sizeof(row)-ri, "\t%f", (double)QDPACK_REAL(qdpack_operator_get(dm_part, j, j))); 108 | //} 109 | //qdpack_file_row_add(filename, row); 110 | 111 | if (i == 0) 112 | { 113 | pe_0_expt_sum += (double)QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1)); 114 | pe_0_expt_no++; 115 | if ((double)QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1)) > pe_0_max) 116 | { 117 | pe_0_max = (double)QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1)); 118 | } 119 | } 120 | if (i == 1) 121 | { 122 | pe_1_expt_sum += (double)QDPACK_REAL(qdpack_operator_get(dm_part, 1, 1)); 123 | pe_1_expt_no++; 124 | } 125 | 126 | qdpack_operator_free(dm_part); 127 | } 128 | 129 | return 0; 130 | } 131 | 132 | 133 | /* --- 134 | * Simulation parameters. 135 | * 136 | */ 137 | double epsilon[] = { 0.0, 8.8, 9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 138 | double delta[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 139 | double ho_w[] = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; 140 | double *lambda[10]; 141 | 142 | 143 | /* --- 144 | * Program starts here. 145 | * 146 | */ 147 | int 148 | main(int argc, char **argv) 149 | { 150 | qdpack_hilbert_space_t *qs; 151 | qdpack_operator_t *rho_q, *rho_c; 152 | qdpack_operator_t *rho0, *rho_t; 153 | qdpack_operator_list_t dm_list; 154 | int qsn, i, noff, nsize, npeak; 155 | double Navg, fw, fA, phi, Gc, Gq, gqc, x, y, pDelta, G1, G2, w0 = 27.3345, Ic = 11.659; 156 | double yi, yf, yd; 157 | 158 | qdpack_simulation_t param; 159 | qdpack_simulation_init(¶m); 160 | 161 | if (argc != 5) 162 | { 163 | printf("usage: %s check code\n", argv[0]); 164 | exit(0); 165 | } 166 | 167 | snprintf(DATADIR, sizeof(DATADIR), DATADIR_TEMPLATE, argv[0]); 168 | 169 | x = strtod(argv[1], NULL); 170 | //y = strtod(argv[2], NULL); 171 | yi = strtod(argv[2], NULL); 172 | yd = strtod(argv[3], NULL); 173 | yf = strtod(argv[4], NULL); 174 | 175 | param.x = x; 176 | 177 | pDelta = 0.0; 178 | fw = x; 179 | G1 = 0.0; 180 | G2 = 0.0; 181 | 182 | param.epsilon = epsilon; 183 | param.delta = delta; 184 | simulation.ho_w = ho_w; 185 | for (i = 0; i < 10; i++) 186 | { 187 | param.epsilon[i] *= 2*M_PI; 188 | param.delta[i] *= 2*M_PI; 189 | simulation.ho_w[i] *= 2*M_PI; 190 | lambda[i] = (double *)calloc(10, sizeof(double)); 191 | } 192 | param.lambda = lambda; 193 | param.lambda[0][1] = 0.000 * 2 * M_PI; 194 | param.lambda[0][2] = 0.000 * 2 * M_PI; 195 | 196 | param.Ti = 0.0; 197 | param.dT = 0.5; 198 | param.Tf = 500.0; 199 | param.cont_basis_transform = 0; 200 | 201 | param.h_td_A = 0.01 * 2 * M_PI; 202 | param.h_td_w = fw * 2 * M_PI; 203 | 204 | param.H1_func = (hamiltonian_func_t)hamiltonian_x_drive; 205 | param.Ht_func = (hamiltonian_td_func_t)hamiltonian_qubit_t; 206 | 207 | /* 208 | * create a new quantum system object 209 | */ 210 | qs = qdpack_hilbert_space_new(); 211 | qdpack_hilbert_space_add(qs, 2); 212 | // qdpack_hilbert_space_add(qs, 2); 213 | // qdpack_hilbert_space_add(qs, 2); 214 | qsn = qdpack_hilbert_space_nstates(qs); 215 | qdpack_hilbert_space_print(qs); 216 | param.qs = qs; 217 | 218 | 219 | /* 220 | * Set up dissipation 221 | * 222 | */ 223 | param.wT = 0.0 * 2 * M_PI; 224 | param.do_n = 0; 225 | Navg = 0; 226 | 227 | 228 | // relaxation 229 | /* 230 | param.do_a[param.do_n] = operator_ho_lowering(qs, 0, 0); 231 | param.do_ad[param.do_n] = operator_ho_raising(qs, 0, 0); 232 | Navg = 0; //1/(exp(sqrt(param.epsilon[0]*param.epsilon[0] + param.delta[0]*param.delta[0])/param.wT) - 1); 233 | printf("qubit Navg = %f\n", Navg); 234 | param.do_g1[param.do_n] = G1 * (1 + Navg); // relaxation 235 | param.do_g2[param.do_n] = G1 * Navg; // excitation 236 | param.do_n++; 237 | */ 238 | /* 239 | // dephasing 240 | param.do_a[param.do_n] = operator_sigma_z(qs, 0); 241 | param.do_ad[param.do_n] = operator_sigma_z(qs, 0); 242 | param.do_g1[param.do_n] = G2 / 2; 243 | param.do_g2[param.do_n] = G2 / 2; 244 | param.do_n++; 245 | */ 246 | snprintf(param.simsig, sizeof(param.simsig), "_G1_%.3f_G2_%.3f_g1_%.3f_g2_%.3h_td_A_%.3f", 247 | G1, G2, lambda[0][1]/(2*M_PI), lambda[0][2]/(2*M_PI), param.h_td_A/(2*M_PI)); 248 | 249 | /* storage space for final rho */ 250 | param.rho_f = qdpack_operator_alloc(qsn, qsn); 251 | 252 | /* 253 | * Setup initial state 254 | */ 255 | qdpack_operator_list_init(&dm_list); 256 | rho_q = qdpack_dm_pure_TLS(0.0); // |0> state 257 | qdpack_operator_list_append(&dm_list, rho_q); // qubit 258 | // qdpack_operator_list_append(&dm_list, rho_q); // tls 259 | // qdpack_operator_list_append(&dm_list, rho_q); // tls 260 | rho0 = qdpack_operator_tensor(qs, &dm_list); 261 | 262 | //delta[0] = pDelta * fw * (2*M_PI); 263 | 264 | printf("ITERATION: %s: x = %f, y = ...\n", param.simsig, param.x); 265 | 266 | for (y = yi; y < yf; y += yd) 267 | { 268 | pe_0_expt_sum = 0.0; 269 | pe_0_expt_no = 0; 270 | pe_1_expt_sum = 0.0; 271 | pe_1_expt_no = 0; 272 | pe_0_max = 0.0; 273 | 274 | param.y = y; 275 | 276 | //epsilon[0] = y * (2*M_PI); 277 | epsilon[0] = w0 * 2 * M_PI * sqrt( sqrt( 1.0 - (y / Ic) * (y / Ic) ) ); 278 | 279 | if (abs(epsilon[0] - param.h_td_w) > 0.5*2*M_PI) 280 | continue; 281 | 282 | param.H0_func = (hamiltonian_func_t)hamiltonian_qubits; 283 | 284 | 285 | /* 286 | * Evolve the quantum system until time t = T, where the steady state 287 | * is assumed to be reached. 288 | * 289 | */ 290 | if (qdpack_evolve_dm_lme_t(qs, rho0, ¶m, rho_store_cb) != 0) 291 | { 292 | fprintf(stderr, "Evolution of the quantum system failed.\n"); 293 | return -1; 294 | } 295 | 296 | rho_store_final_cb(param.rho_f, param.Tf, qs, ¶m); 297 | 298 | } 299 | 300 | return 0; 301 | 302 | } 303 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /qdpack/gsl_ext.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Copyright (C) 2012, Robert Johansson 3 | // All rights reserved. 4 | // 5 | // This file is part of QDpack, and licensed under the LGPL. 6 | // http://dml.riken.jp/~rob/qdpack.html 7 | //------------------------------------------------------------------------------ 8 | 9 | #include 10 | 11 | #include "gsl_ext.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | 22 | // XXX: find the correct header file to included instead of this declaration 23 | int zgeev_(char *jobvl, char *jobvr, integer *n, 24 | doublecomplex *a, integer *lda, doublecomplex *w, doublecomplex *vl, 25 | integer *ldvl, doublecomplex *vr, integer *ldvr, doublecomplex *work, 26 | integer *lwork, doublereal *rwork, integer *info); 27 | 28 | /* 29 | * Convert a real valued GSL matrix to a complex valued GSL matrix. 30 | * 31 | */ 32 | int 33 | gsl_ext_matrix_convert(gsl_matrix_complex *dst, gsl_matrix *src) 34 | { 35 | unsigned int i, j; 36 | gsl_complex z; 37 | 38 | if (src->size1 != dst->size1 || src->size2 != dst->size2) 39 | return -1; 40 | 41 | for (i = 0; i < src->size1; i++) 42 | { 43 | for (j = 0; j < src->size1; j++) 44 | { 45 | GSL_SET_COMPLEX(&z, gsl_matrix_get(src, i, j), 0.0); 46 | gsl_matrix_complex_set(dst, i, j, z); 47 | } 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | /* 54 | * Allocate a complex matrix, convert the real matrix it complex form 55 | * and free the real matrix. 56 | * 57 | */ 58 | gsl_matrix_complex * 59 | gsl_ext_matrix_convert_and_free(gsl_matrix *m) 60 | { 61 | gsl_matrix_complex *zm; 62 | 63 | zm = gsl_matrix_complex_alloc(m->size1, m->size2); 64 | 65 | gsl_ext_matrix_convert(zm, m); 66 | 67 | gsl_matrix_free(m); 68 | 69 | return zm; 70 | } 71 | 72 | /* 73 | * Calculate the matrix exponent of A and store in eA. 74 | * Algorithm: Truncated Talyor series. 75 | * 76 | * WARNING: Large errors possible and it's slow. 77 | */ 78 | int 79 | gsl_ext_expm_complex(gsl_matrix_complex *A, gsl_matrix_complex *eA) 80 | { 81 | int i; 82 | gsl_complex alpha, beta, z; 83 | gsl_matrix_complex *I, *T; 84 | 85 | I = gsl_matrix_complex_alloc(A->size1, A->size2); 86 | T = gsl_matrix_complex_alloc(A->size1, A->size2); 87 | 88 | GSL_SET_COMPLEX(&alpha, 1.0, 0.0); 89 | GSL_SET_COMPLEX(&beta, 0.0, 0.0); 90 | 91 | gsl_matrix_complex_set_identity(I); 92 | gsl_matrix_complex_set_identity(eA); 93 | 94 | for (i = 50; i > 0; i--) 95 | { 96 | GSL_SET_COMPLEX(&z, 1.0 / i, 0.0); 97 | gsl_matrix_complex_scale(eA, z); 98 | 99 | gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, alpha, eA, A, beta, T); 100 | gsl_matrix_complex_add(T, I); 101 | gsl_matrix_complex_memcpy(eA, T); 102 | } 103 | 104 | return 0; 105 | } 106 | 107 | /* 108 | * Calculate eigenvectors and eigenvalues for a non-symmetric complex matrix 109 | * using the CLAPACK zgeev_ function. 110 | * 111 | */ 112 | int 113 | gsl_ext_eigen_zgeev(gsl_matrix_complex *A_gsl, gsl_matrix_complex *evec, gsl_vector_complex *eval) 114 | { 115 | //integer *pivot; 116 | integer n,i,j,info,lwork, ldvl, ldvr, lda; 117 | doublecomplex *A,*vr,*vl,*w,*work; 118 | doublereal *rwork; 119 | char jobvl,jobvr; 120 | 121 | n = A_gsl->size1; 122 | 123 | // pivot = (integer *)malloc((size_t)n * sizeof(int)); 124 | A = (doublecomplex *)malloc((size_t)n * n * sizeof(doublecomplex)); 125 | w = (doublecomplex *)malloc((size_t)n * sizeof(doublecomplex)); 126 | vr = (doublecomplex *)malloc((size_t)n * n * sizeof(doublecomplex)); 127 | vl = (doublecomplex *)malloc((size_t)n * n * sizeof(doublecomplex)); 128 | lwork = 16 * n; 129 | work = (doublecomplex *)malloc((size_t)lwork * sizeof(doublecomplex)); 130 | rwork = (doublereal *)malloc((size_t)lwork * sizeof(doublereal)); 131 | 132 | for (i = 0; i < n; i++) 133 | { 134 | for (j = 0; j < n; j++) 135 | { 136 | gsl_complex z; 137 | double re,im; 138 | 139 | z = gsl_matrix_complex_get(A_gsl, i, j); 140 | re = GSL_REAL(z); 141 | im = GSL_IMAG(z); 142 | 143 | A[j*n+i] = (doublecomplex){re,im}; 144 | } 145 | } 146 | 147 | jobvl='N'; 148 | jobvr='V'; 149 | 150 | lda = n; 151 | ldvr = n; 152 | ldvl = n; 153 | zgeev_(&jobvl, &jobvr, &n, A, &lda, w, vl, &ldvl, vr, &ldvr, work, &lwork, rwork, &info); 154 | 155 | //ZGEEVX(BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, W, VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM, RCONDE, RCONDV, WORK, LWORK, RWORK, INFO ) 156 | 157 | for (i = 0; i < n; i++) 158 | { 159 | gsl_complex z; 160 | GSL_SET_COMPLEX(&z, w[i].r, w[i].i); 161 | gsl_vector_complex_set(eval, i, z); 162 | } 163 | 164 | for (j = 0; j < n; j++) 165 | { 166 | for (i = 0; i < n; i++) 167 | { 168 | gsl_complex z; 169 | 170 | GSL_SET_COMPLEX(&z, vr[j*n+i].r, vr[j*n+i].i); 171 | 172 | gsl_matrix_complex_set(evec, i, j, z); 173 | } 174 | } 175 | 176 | if (info != 0) 177 | { 178 | printf("zgeev_: error: info = %d\n", (int)info); 179 | } 180 | 181 | // free(pivot); 182 | free(A); 183 | free(w); 184 | free(vr); 185 | free(vl); 186 | free(work); 187 | free(rwork); 188 | 189 | return 0; 190 | } 191 | 192 | /** ---------------------------------------------------------------------------- 193 | * Sort eigenvectors 194 | */ 195 | int 196 | gsl_ext_eigen_sort(gsl_matrix_complex *evec, gsl_vector_complex *eval, int sort_order) 197 | { 198 | gsl_complex z; 199 | 200 | gsl_matrix_complex *evec_copy; 201 | gsl_vector_complex *eval_copy; 202 | 203 | int *idx_map, i, j, idx_temp; 204 | 205 | double p1, p2; 206 | 207 | if ((evec->size1 != evec->size2) || (evec->size1 != eval->size)) 208 | { 209 | return -1; 210 | } 211 | 212 | evec_copy = gsl_matrix_complex_alloc(evec->size1, evec->size2); 213 | eval_copy = gsl_vector_complex_alloc(eval->size); 214 | 215 | idx_map = (int *)malloc(sizeof(int) * eval->size); 216 | 217 | gsl_matrix_complex_memcpy(evec_copy, evec); 218 | gsl_vector_complex_memcpy(eval_copy, eval); 219 | 220 | // calculate new eigenvalue order 221 | 222 | for (i = 0; i < eval->size; i++) 223 | { 224 | idx_map[i] = i; 225 | } 226 | 227 | for (i = 0; i < eval->size - 1; i++) 228 | { 229 | for (j = i+1; j < eval->size; j++) 230 | { 231 | idx_temp = -1; 232 | 233 | if (sort_order == GSL_EXT_EIGEN_SORT_ABS) 234 | { 235 | p1 = gsl_complex_abs(gsl_vector_complex_get(eval, idx_map[i])); 236 | p2 = gsl_complex_abs(gsl_vector_complex_get(eval, idx_map[j])); 237 | if (p1 > p2) 238 | { 239 | idx_temp = idx_map[i]; 240 | } 241 | } 242 | 243 | if (sort_order == GSL_EXT_EIGEN_SORT_PHASE) 244 | { 245 | p1 = gsl_complex_arg(gsl_vector_complex_get(eval, idx_map[i])); 246 | p2 = gsl_complex_arg(gsl_vector_complex_get(eval, idx_map[j])); 247 | 248 | if (p1 > M_PI) p1 -= 2*M_PI; 249 | if (p1 <= -M_PI) p1 += 2*M_PI; 250 | 251 | if (p2 > M_PI) p2 -= 2*M_PI; 252 | if (p2 <= -M_PI) p2 += 2*M_PI; 253 | 254 | //if (((p2 < p1) && (p1 - p2 < M_PI)) || ) 255 | if (p2 < p1) 256 | { 257 | idx_temp = idx_map[i]; 258 | } 259 | } 260 | 261 | if (idx_temp != -1) 262 | { 263 | // swap 264 | //idx_temp = idx_map[i]; 265 | idx_map[i] = idx_map[j]; 266 | idx_map[j] = idx_temp; 267 | } 268 | } 269 | } 270 | 271 | // reshuffle the eigenvectors and eigenvalues 272 | for (i = 0; i < eval->size; i++) 273 | { 274 | for (j = 0; j < eval->size; j++) 275 | { 276 | z = gsl_matrix_complex_get(evec_copy, idx_map[i], j); 277 | gsl_matrix_complex_set(evec, i, j, z); 278 | //z = gsl_matrix_complex_get(evec_copy, i, idx_map[j]); 279 | //gsl_matrix_complex_set(evec, i, j, z); 280 | } 281 | 282 | z = gsl_vector_complex_get(eval_copy, idx_map[i]); 283 | gsl_vector_complex_set(eval, i, z); 284 | } 285 | 286 | gsl_matrix_complex_free(evec_copy); 287 | gsl_vector_complex_free(eval_copy); 288 | 289 | free(idx_map); 290 | 291 | return 0; 292 | } 293 | 294 | /** ---------------------------------------------------------------------------- 295 | * Normalize eigenvectors 296 | * / 297 | int 298 | gsl_ext_eigen_norm(gsl_matrix_complex *evec) 299 | { 300 | gsl_complex z, w; 301 | 302 | if ((evec->size1 != evec->size2)) 303 | { 304 | return -1; 305 | } 306 | 307 | // normalize each column 308 | for (i = 0; i < evec->size1; i++) 309 | { 310 | GSL_SET_COMPLEX(&z, 0.0, 0.0); 311 | 312 | for (j = 0; j < evec->size2; j++) 313 | { 314 | z = gsl_complex_add(z, gsl_matrix_complex_get(evec, idx_i, j)); 315 | } 316 | 317 | for (j = 0; j < evec->size2; j++) 318 | { 319 | z = gsl_complex_add(z, gsl_matrix_complex_get(evec, idx_i, j)); 320 | } 321 | 322 | gsl_matrix_complex_set(evec, i, j, z); 323 | z = gsl_vector_complex_get(eval_copy, idx_map[i]); 324 | gsl_vector_complex_set(eval, i, z); 325 | } 326 | 327 | return 0; 328 | } 329 | */ 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | --------------------------------------------------------------------------------