Saturday, February 25, 2012

Write vectors as an ASCII file

In this first post we will create 2 vectors and write them into a file.

Python can be used interactively, with classical call to python from the command line or by running iPython. In the following, I will mainly use iPython, which provides a lot of tools to help the user interacting with its variables and programs.

Use copy-paste to execute the commands found in this color in the following, in an interactive python or ipython shell. The outputs from python are in this color.

We can also put all the commands in a file and execute it from python (we'll come back to this latter).

As we want to use vectors and perform operations on them, we need an additional library called numpy.
To import this library, we will write at the very beginning of the session (or the file):
import numpy

Everything depending on numpy will be called using numpy. before its name (Notice the point after numpy). For example, if we need to create an array with 10 elements named a, we do:

a = numpy.arange(10)

Given that it's a little heavy to have to write numpy. a lot of times, we can alias this when importing the package, so that we only need to use np.:

import numpy as np
a = np.arange(10)

You can print out the value of a by just typing "a" and ENTER:
a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 

The output can differ if you use iPython:
In [2]: a
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

One can also print a:
print a
[0 1 2 3 4 5 6 7 8 9]

We want to create 2 vectors: x and y = sin(x). We will first define some variables holding the parameters of the vectors:
x_min = 0.
x_max = 3 * np.pi
n_steps = 100

To generate an array of n_steps values ranging from x_min to x_max, use linspace:
x = np.linspace(x_min, x_max, n_steps)

x is a numpy array, which support arithmetic operations like :
y = x**2
It can be used as argument for functions who will apply on each element of the array and return an array of the result. The trigonometrical functions are also available from numpy, so we use np. to access it:
y = np.sin(x)

We now want to store the 2 vectors as 2 columns of an ASCII file.
We first open the file, named 'datas'. We tell python that we will write to it, using 'w':
f = open('datas.dat', 'w')
f is an object (everything in Python is an object ;-) ), and one can play with some function that apply to f or some variable related to f directly by calling them using f. (notice the point after f):
print f.name, f.mode
datas w
We have to loop on the different elements of x and y to write them. The indexes in Python start at 0. The function np.arange(n) returns a list of integer from 0 to n-1, exactly what we need to scan the values of the two arrays x and y.
The loop is classically defined by a for instruction. In Python, the start of a block (for, while, if, etc.. blobk) is delimited by :, and the block is defined by indentation:
for i in np.arange(n_steps): 
    f.write('{0:f} {1:f} \n'.format(x[i], y[i]))
f.close()

We see that the f.write is indented: this is the block (here a single line, but can be very bigger) on which the loop is run. The instruction to close the file f.close() is written at the beginning of the line, no more indentation, so the loop is terminated.
The format to write x[i] and y[i] is '{0:f} {1:f} \n'.
{0:f} is to tell python to write the first variable in format(x[i], y[i]), namely x[i], as floating points.
\n is to go to the next line. We will have a post dedicated to formats latter, you can already have a look at some links below.

One can copy-paste all the previous commands in a python session, or write all in a file, to be run directly.

The python program is there:

#! /usr/bin/env python
#Need to import numpy:

import numpy as np

# define some variables:
x_min = 0.
x_max = 3 * np.pi
n_steps = 100
# create a vector from x_min to x_max, with n_steps elements
x = np.linspace(x_min, x_max, n_steps)
# create a 2nd vector, as a function of x
y = np.sin(x)

# Write x and y into a file
f = open('datas.dat', 'w')
for i in np.arange(n_steps):
# could have been: for xx, yy in zip(x,y):
    f.write('{0:f} {1:f} \n'.format(x[i], y[i]))
f.close()

Save it somewhere with the name Ex1.py.
You can run it from the shell by:
LINUX> python Ex1.py

With the help of the first line #! /usr/bin/env python, once the Ex1.py file is set to executable (chmod a+x Ex1.py), it's possible to run it directly:
LINUX> ./Ex1.py

or from python:
import Ex1
Notice that import actually also executes any instruction in the imported file.

or from ipython
In [1]: %run Ex1

The file "datas.dat" should contains the x and y values, in 2 columns, like this:
0.000000 0.000000
0.095200 0.095056
0.190400 0.189251
0.285599 0.281733
0.380799 0.371662
0.475999 0.458227
0.571199 0.540641
0.666398 0.618159
0.761598 0.690079
0.856798 0.755750
...

To lear more on files:
To learn more on string format:

1 comment: