Introducing Python and the IPython Notebook
Although TRIQS tools are primarily written in C++, they have a user interface written in python. Python scripts control most calculations, pre- and post-processing of the data, choice of DMFT scheme, plotting, etc. We chose to use Python because it is a very simple and intuitive language. As an interpreted language, Python eliminates the need to recompile code if you decide to change variables, add some extra pieces of data analysis, etc.
Below, we provide a brief overview of some core aspects of the language. For a thorough introduction to Python for scientific data analysis we recommend these resources:
Python can be used either in interactive or in script mode.
Script mode
In script mode, you edit a file (with an extension .py), say my_script.py, and run it with Python. You do this from a shell:
>>> python my_script.py
Interactive shell mode
You can also type directly in the shell
>>> ipython
This will bring you into interactive mode. You can type commands one after the other and they are executed on the fly.
The IPython Notebook
You are currently viewing an IPython notebook. This interactive environment displays all your commands appearing in a “Mathematica”-like notebook. The advantage, as we will see, is that the result of commands, even plots, directly appears and stays in the notebook.
Let’s begin with a simple example to execute in the notebook. To do so, click on the input line below and execute it with Shift+Enter
[1]:
print("Hello world!")
Hello world!
The result of the command appears above.
Exercise
As an exercise, run this same command
using the script mode (edit a my_script.py file, add the print line above and execute the file from a shell)
in interactive shell mode (you quit the interactive mode with Ctrl+d)
A Very Short Introduction to Python
For a thorough introduction to Python we advise the reader to follow the tutorial at the following link:
In the following we will only present a set of self-explanatory examples that can help you get started quickly.
Calculating
[2]:
# Comments start with a #
# Setting variables and doing calculations
x = 3
y = 6.7
print('first result: ', (x+y)/4.2)
# Using complex numbers
i = 1j
print('i^2: ', i*i)
print('complex calculation: ', (2+4j)*(4-2j))
first result: 2.3095238095238093
i^2: (-1+0j)
complex calculation: (16+12j)
Simple loops / indentation
[3]:
# Look how indentation is used in python to define code blocks
# Also note that range(5) produces numbers from 0 to 4
x = 1
for i in range(5):
x = x + i
print("i = ", i)
print("x = ", x)
print("That's it!")
i = 0
x = 1
i = 1
x = 2
i = 2
x = 4
i = 3
x = 7
i = 4
x = 11
That's it!
If statements
[4]:
# Comparing symbols are == (equal), != (not equal), >, <, <=, >=, etc.
for i in range(0, 10, 2):
if i == 4:
print("i is 4")
elif i == 6:
print("i is 6")
else:
print("i is different")
i is different
i is different
i is 4
i is 6
i is different
Defining a function
[5]:
# Define a new function
def fnct(x):
y = x**2 - 5.0
return y
print(fnct(3.))
4.0
Importing modules
[6]:
# In order to have access to new functions, you
# import them from a library. Here we import mathematical functions
# from the math library. After the import, python knows about
# cos and pi
# to import everything in module math:
# from math import *
from math import cos,pi
print("cos(pi/2) = %.3f"%(cos(pi/2.0)))
print("cos(pi) = %.3f"%(cos(pi)))
cos(pi/2) = 0.000
cos(pi) = -1.000
Lists
[7]:
# Lists are defined with []
# Note that indices start at 0 (not 1 like in Fortran)
l = [1,2,3,4]
print("The second element of l is ", l[1])
# Lists are not vectors, adding lists appends them
l2 = [5,6]
l3 = l+l2
print("l3 is ", l3)
The second element of l is 2
l3 is [1, 2, 3, 4, 5, 6]
The NumPy Library
NumPy is an important scientific library in Python. It mainly allows you to manipulate arrays (matrices and vectors) and do linear algebra with them.
[8]:
from numpy import array,dot
# vectors
v = array([1,1,2,3])
w = array([1,1,1,1])
print("Adding term by term: ", v+w)
print("dot product: ", dot(v,w))
# matrices
A = array([[1,0],[0,1]])
B = array([[1,2],[3,4]])
print("A x B = ")
print(dot(A,B))
Adding term by term: [2 2 3 4]
dot product: 7
A x B =
[[1 2]
[3 4]]
Defining a new class
This is for those that already know about object-oriented languages. in Python, just like C++ for example, you can define your own classes. Here’s an example:
[9]:
# A new class
# Note that all member functions must have "self" as a first argument
class MyObject:
# The constructor is called __init__
def __init__(self, x):
self.x = x
def what_is_x(self):
print("x is ", self.x)
def change_x(self, x):
self.x = x
A = MyObject(10)
A.what_is_x()
A.change_x(12)
A.what_is_x()
x is 10
x is 12
Getting help
When you put a question mark after a command and type Ctrl-Enter it gives the help. If you type the parenthesis and then press Tab it will tell you what arguments are expected.
[10]:
array?
Python Library Documentation: built-in function array in module numpy
array(...)
array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0,
like=None)
Create an array.
Parameters
----------
object : array_like
An array, any object exposing the array interface, an object whose
``__array__`` method returns an array, or any (nested) sequence.
If object is a scalar, a 0-dimensional array containing object is
returned.
dtype : data-type, optional
The desired data-type for the array. If not given, NumPy will try to use
a default ``dtype`` that can represent the values (by applying promotion
rules when necessary.)
copy : bool, optional
If ``True`` (default), then the array data is copied. If ``None``,
a copy will only be made if ``__array__`` returns a copy, if obj is
a nested sequence, or if a copy is needed to satisfy any of the other
requirements (``dtype``, ``order``, etc.). Note that any copy of
the data is shallow, i.e., for arrays with object dtype, the new
array will point to the same objects. See Examples for `ndarray.copy`.
For ``False`` it raises a ``ValueError`` if a copy cannot be avoided.
Default: ``True``.
order : {'K', 'A', 'C', 'F'}, optional
Specify the memory layout of the array. If object is not an array, the
newly created array will be in C order (row major) unless 'F' is
specified, in which case it will be in Fortran order (column major).
If object is an array the following holds.
===== ========= ===================================================
order no copy copy=True
===== ========= ===================================================
'K' unchanged F & C order preserved, otherwise most similar order
'A' unchanged F order if input is F and not C, otherwise C order
'C' C order C order
'F' F order F order
===== ========= ===================================================
When ``copy=None`` and a copy is made for other reasons, the result is
the same as if ``copy=True``, with some exceptions for 'A', see the
Notes section. The default order is 'K'.
subok : bool, optional
If True, then sub-classes will be passed-through, otherwise
the returned array will be forced to be a base-class array (default).
ndmin : int, optional
Specifies the minimum number of dimensions that the resulting
array should have. Ones will be prepended to the shape as
needed to meet this requirement.
like : array_like, optional
Reference object to allow the creation of arrays which are not
NumPy arrays. If an array-like passed in as ``like`` supports
the ``__array_function__`` protocol, the result will be defined
by it. In this case, it ensures the creation of an array object
compatible with that passed in via this argument.
.. versionadded:: 1.20.0
Returns
-------
out : ndarray
An array object satisfying the specified requirements.
See Also
--------
empty_like : Return an empty array with shape and type of input.
ones_like : Return an array of ones with shape and type of input.
zeros_like : Return an array of zeros with shape and type of input.
full_like : Return a new array with shape of input filled with value.
empty : Return a new uninitialized array.
ones : Return a new array setting values to one.
zeros : Return a new array setting values to zero.
full : Return a new array of given shape filled with value.
copy: Return an array copy of the given object.
Notes
-----
When order is 'A' and ``object`` is an array in neither 'C' nor 'F' order,
and a copy is forced by a change in dtype, then the order of the result is
not necessarily 'C' as expected. This is likely a bug.
Examples
--------
>>> import numpy as np
>>> np.array([1, 2, 3])
array([1, 2, 3])
Upcasting:
>>> np.array([1, 2, 3.0])
array([ 1., 2., 3.])
More than one dimension:
>>> np.array([[1, 2], [3, 4]])
array([[1, 2],
[3, 4]])
Minimum dimensions 2:
>>> np.array([1, 2, 3], ndmin=2)
array([[1, 2, 3]])
Type provided:
>>> np.array([1, 2, 3], dtype=complex)
array([ 1.+0.j, 2.+0.j, 3.+0.j])
Data-type consisting of more than one element:
>>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')])
>>> x['a']
array([1, 3], dtype=int32)
Creating an array from sub-classes:
>>> np.array(np.asmatrix('1 2; 3 4'))
array([[1, 2],
[3, 4]])
>>> np.array(np.asmatrix('1 2; 3 4'), subok=True)
matrix([[1, 2],
[3, 4]])