========= C and C++ ========= Here are some tips for those who wish to use the `compiled programming language `__ C or C++ for scientific work instead of some `interpreted programming language `__ (Matlab, ...). I assume, that you have some understanding of the fundamentals of the syntax of C and C++ but you are looking for high level functionality such as plotting, random number generation and handling of matrices. I recommend two styles: A. If you are using plain C, then I suggest to use the `GSL (Gnu Scientific Library) `__. #. If you are using C++, then I suggest to use the `boost library `__. I explain my ideas by giving examples. Visualization ============= Since most scientific writing is done in ``LaTeX`` I suggest to visualize data as follows. In the program, the data is written to a text file. Then we use the ``LaTeX`` package `pgfplots `__ to plot this data. (See my examples in the :ref:`Graphics in LaTeX with PGF ` section.) Consider the following three files: #. The C style file ``viz.c``: .. literalinclude:: c-and-c++/viz.c :language: c #. The C++ style file ``viz.cpp``: .. literalinclude:: c-and-c++/viz.cpp :language: c++ #. Finally the ``LaTeX`` file ``viz.tex``: .. literalinclude:: c-and-c++/viz.tex :language: latex We can compile the C file or the C++ file with the `GNU compiler `__. The resulting program produces our data file ``viz.dat`` which we want to plot. Finally, we use ``LaTeX`` to produce a pdf file containing the plot. The sequence of commands for the C style file is:: gcc viz.c -lm ./a.out pdflatex viz.tex The sequence of commands for the C++ style file is:: g++ viz.cpp ./a.out pdflatex viz.tex The plot should look as follows: .. tikz:: :stringsubst: \begin{axis} \addplot table[x=t,y=sin] {$wd/comp/prog/c-and-c++/viz.dat}; \addplot table[x=t,y=exp] {$wd/comp/prog/c-and-c++/viz.dat}; \legend{Sinusoid,Exponential} \end{axis} Random Numbers ============== In plain C, GSL provides good random number generators. The following example uses the default generator: (Compile with ``gcc random.c -lgsl -lgslcblas``.) .. literalinclude:: c-and-c++/random.c :language: c In C++, boost provides good random number generators. The following example uses a Mersenne Twister generator. (Compile with ``g++ random.cpp``.) .. literalinclude:: c-and-c++/random.cpp :language: c++ .. note:: Starting from boost version 1.47, the random number part of the boost library has been moved to the namespace ``boost/random`` and header files are split up in several files. The first lines of this example have to be changed to .. code-block:: c++ #include #include #include #include #include using namespace std; using namespace boost::random; The resulting data should look as follows: .. tikz:: :stringsubst: \begin{axis} \addplot table[x=t,y=sin]{$wd/comp/prog/c-and-c++/random.dat}; \addplot table[x=t,y=noisy]{$wd/comp/prog/c-and-c++/random.dat}; \legend{Sinusoid, Noisy} \end{axis} Matrix Inversion ================ In plain C, GSL provides structures for matrices and vectors. A general non-singular matrix can be inverted using the LU-factorization as shown in the following example ``matrix-inverse.c``. (Compile with ``gcc matrix-inverse.c -lgsl -lgslcblas``.) .. sidebar:: Example output With high probability the matrix ``A`` is non-singular and the output is, e.g.:: A = 0.0133919 -0.0088101 0.167441 0.0733641 0.0997525 -0.12775 -0.239672 -0.067928 -0.00390913 A*Ai= 1 0 -1.38778e-17 0 1 5.55112e-17 -2.08167e-17 1.03216e-16 1 Ai*A= 1 -5.55112e-17 -7.97973e-17 0 1 -3.46945e-18 0 6.93889e-18 1 done .. literalinclude:: c-and-c++/matrix-inverse.c :language: c In C++, we use again ``boost`` and ``boost::ublas`` to perform the same matrix inversion based on the LU-factorization as shown in the following example ``matrix-inverse.cpp``. (Compile with ``g++ matrix-inverse.cpp``.) .. literalinclude:: c-and-c++/matrix-inverse.cpp :language: c++ An example output is, e.g.:: A = [3,3]((0.357628,0.14061,1.39772),(0.0460402,-1.46791,-0.770404),(0.274781,-0.892802,1.63291)) Ai = [3,3]((4.84101,2.31866,-3.04983),(0.450192,-0.313718,-0.533363),(-0.568484,-0.561703,0.833999)) Ai*A = [3,3]((1,8.88178e-16,-1.77636e-15),(0,1,-1.11022e-16),(-2.77556e-17,-1.11022e-16,1)) A*Ai = [3,3]((1,0,0),(0,1,-1.11022e-16),(-3.33067e-16,0,1))