Mostrando las entradas con la etiqueta Cpp. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Cpp. Mostrar todas las entradas

jueves, 2 de junio de 2016

Installation of MathGL 2.3.5 In Debian

Installation of MathGL 2.3.5 In Debian

Motivation

Despite that MathGL is included in the official Debian repositories, It is not the latest version, and the installed, library includes a lot of wrappers and features I'm unlikely to use.

What is MathGL?

As the official website states, MathGL is,

  • a library for making high-quality scientific graphics under Linux and Windows.
  • a library for the fast data plotting and data processing of large data arrays.
  • a library for working in window and console modes and for easy embedding into other programs.
  • a library with large and growing set of graphics.

Here you can see a gallery with MathGL graphics

I've used this library several times from long time ago (like in this project of Hodgking-Huxley action potential) and I think is a very nice library to generate graphics from your final binaries. For example, I've used it when my code is up and running and I want it to generate graphic output directly (png,pdf,...)


Installation

First of all, download the latest source from here, and then proceed to get the required prerequisistes.

Prerequisites

The list of prerequisites depends a lot on what you'd like to do with MathGL. I wanted to be able to work with Qt5 widgets, pdf output,gsl support (GNU Scientifical library),OpenMP, MPI, HDF5, and wxWidget support. I've installed the required libraries as root by,


To see the complete list of supported features you can read the CMakeLists.txt and look for every line containing option(enable-XYZ) so you add -D enable-XYZ when you call cmake.

Building MathGL

Once you've installed the prerequisites, you can build MathGL at the root directory of the source or simply a build directory. I like more the build approach since keeps the source directory clean.


Any errors during the cmake phase can be related to the lack of any prerequisite so keep an eye on the errors, they often say what needs to get installed or fixed.

If everything goes fine, you finally install MathGL as root by,

make install

And that's it.

Resources


lunes, 9 de mayo de 2016

C++ seems faster than C at summing big arrays!!

Forewords

I'm some sort of self-taught programer, so it is expected that my methods and algorithms aren't state of the art optimized to best design practices and improved performance. I made the code without thinking on but doing the tast and leaving aside the code optimization and all that stuff.

The result here is just what I have found. I think that sitting and optimizing code could turn tables, but, not anyone is capable of efficiently write code (a.k.a. optimizing it for best performance), specially if you are a scientist coding (and not a computer scientist).


Motivation

For several months I've been wondering whether C or C++ is more efficient at doing science related tasks. As far as I know, the most common tasks in science involve linear algebra, and one of the simplest tasks is the sum of vectors. Given that I'm preparing some study materials I've decided to test it out and here is what i've found so far.


C++ seems faster than C at summing big arrays of integers

I made codes that compares the performance between regular C arrays (also C++ valid arrays) and STL arrays (exclusive of C++) by taking two random vectors up to 200000 components as input from a file.

One program run consist of,

  • Read a 1000 components of two random vectors from a given file.
  • Sum component to component the couple of vectors read. Report the number of components and the milliseconds it took for the whole process to standard output.
  • Increase the number of components by 1000, then repeat the read-sum-report procedure stated above.
  • Repeat increasing size until the vectors reach 200000 components.

The codes are available here


Results

Well, using my unoptimized algorithm it seems that C++ is indeed a little bit faster than C.
The time-to-completion was measured 300 times on the same machine, the resulting run-times where averaged to compensate the effects of anyother processes running.
A fitting to linear functions seemed suitable for the resulting data. The blue marks on the graph represent C++ run-times whilst purple marks represent those of C.
The fitting was made using gnuplot with the fit function: f(x) for C and g(x) for C++ (details below)


C vs C++ Benchmarking


Fitting for C with f(x)

f(x)=A*x+B

The relevant output of the fitting was


After 8 iterations the fit converged.
final sum of squares of residuals : 68.4475
relative change during last iteration : -1.00902e-13

degrees of freedom (FIT_NDF) : 197
rms of residuals (FIT_STDFIT) = sqrt(WSSR/ndf) : 0.589448
variance of residuals (reduced chisquare) = WSSR/ndf : 0.347449

Final set of parameters Asymptotic Standard Error
======================= ==========================
A = 0.000385433 +/- 7.274e-07 (0.1887%)
B = 1.36903 +/- 0.08389 (6.127%)

Fitting for C++ with g(x)


function used for fitting: g(x)
g(x)=C*x+D

After 8 iterations the fit converged. q
final sum of squares of residuals : 48.4348
relative change during last iteration : -1.78975e-14

degrees of freedom (FIT_NDF) : 197
rms of residuals (FIT_STDFIT) = sqrt(WSSR/ndf) : 0.495845
variance of residuals (reduced chisquare) = WSSR/ndf : 0.245862

Final set of parameters Asymptotic Standard Error
======================= ==========================
C = 0.000367315 +/- 6.119e-07 (0.1666%)
D = 1.16317 +/- 0.07056 (6.067%)


Conclusions

At the beginning, the execution times of both languages are undistinguishable but it seems that C++ has better performance than C as the size of the vectors increase. It could be a matter of design, more test with different algorithms should be performed.

The difference between the fitted curves is the linear function
D(x) = f(x) - g(x) = 0.000018118*x-0.20586
Clearly when N=10 000 000 the difference between runtimes would be of just 17.91214 ms so whats the point of using C++ over C if the performance difference would be so small? Well, because of Object Oriented Programming, that's why. Besides, the C++ std::array are expected to be optimized over the regular int array[] of C.

domingo, 16 de febrero de 2014

Editores de texto y programación - mi perspectiva desde el uso, el abuso y la desazón

Todo estudiante de ciencias* pasa por aquella época de la vida donde debe programar (o por lo menos, intentarlo). Dejando de lado todas las peripecias asociadas con esta empresa, quiero concentrar esta entrada en mi experiencia personal con los editores de texto y los entornos integrados de programación (IDE).
* se habla de lo que se conoce.

Emacs

Emacs forma parte de la comunidad GNU. Si bien, es un editor de texto útil, la necesidad recurrente de atajos de teclado que no podía memorizar fácilmente me hacían perderle un poco el respeto.
Se comporta muy bien al trabajar desde consola, pero también ofrece una interfaz gráfica.
Una de las características más llamativas es la gran cantidad de plug-ins disponibles. Por ejemplo, hay un plugin para integrar emacs sistemas de control de versiones (como git), hay un plugin de WYSIWYG para la edición de textos en latex. La lista sigue, incluso hay plugins que ofrecen juegos de arcade.
No recomendaría este editor para los neófitos en la programación, suelo bromear diciendo que emacs es el editor de texto preferido de Davy Jones

Así se sienten los atajos de teclado demasiado largos

KDevelop

Fui usuario asiduo del entorno de escritorio KDE. Un día por recomendación de un amigo me enteré de la existencia de KDevelop, un entorno de desarrollo muy poderoso. Igual que emacs posee reconocimiento de sintaxis en varios lenguajes, y permite configurar control de versiones con git. Otra característica importante es el autocompletado de palabras, lo cual acelera el proceso de escritura. Toda una maravilla si se tiene suficiente RAM a disposición.
Pero como todo en la vida, no hay nada perfecto: los requisitos de memoria del KDevelop, así como una reciente racha de crashes hicieron que retomase mis intentos por utilizar un editor que había probado tiempo atrás: Vim

VIM (VI Improved)

Vim pareciera ser un editor de texto bastante simple, sin embargo, no hay que dejarse engañar. Puedo resumir diciendo que vim es uno de los editores de texto más potentes que he podido utilizar. Posee gran versatilidad en su sistema de comandos, además de reconocer la sintaxis de más de 200 lenguajes de programación (incluyendo TeX y Latex), permite una personalización muy amplia al punto de permitir cosas como definir sistemas de resaltado de sintaxis propios, esquemas de color y comandos personalizados. Comparándolo con emacs, vim utiliza instrucciones más simples y fáciles de recordar, tan sencillas que es posible programar usando una mano (obviamente son escasas las situaciones donde esto será necesario). Además de su versatilidad, la curva de aprendizaje es suave y basta con usarlo por algunas horas para acoplarse a esta "power tool" como lo llama su creador. Sin lugar a dudas, uno de los mejores editores que he utilizado.
Me llamó mucho la atención enterarme que vim forma parte de una campaña para apoyar niños en Uganda a través de donaciones. Buen trabajo equipo vim!!!

Vim: The power tool for everyone!
El proceso de personalización el editor vim toma tiempo, hay un sitio en particular donde se puede aprender como. Un amigo mío dispone de un repositorio en github donde publica un conjunto de configuraciones muy útiles para quienes programamos en C++, los invito a que se den una pasada por https://github.com/muzgash/vim


Y a que viene todo esto?

El proceso de programación y escritura debe ser una experiencia reconfortante, por lo tanto es importante disponer de un buen editor de texto. Para programar puede usarse cualquier editor de texto y cada cual elije el editor que más le convenga en función de sus necesidades particulares. Opté por mencionar los editores de texto más significativos entre los que he usado durante mis proyectos de programación (que consisten básicamente en aprendizaje de lenguajes). Dentro de los editores que he probado están UltraEdit(Windows), Geany (Un IDE escrito en GTK), Kate, y la lista se extiende.
Pese a todo, lo que importan son las habilidades de programación que se tienen, y no el editor se use para programar.

Enlaces de interés

  1. Página del proyecto GNU Emacs http://www.gnu.org/software/emacs/
  2. Página del proyecto KDevelop http://kdevelop.org/
  3. Página del proyecto VIM http://www.vim.org/about.php
  4. Repositorio de configuraciones de VIM https://github.com/muzgash/vim
  5. IDE Geany http://www.geany.org/
  6. Para aprender a usar vim http://code.tutsplus.com/articles/25-vim-tutorials-screencasts-and-resources--net-14631
  7. Para aprender más de otros editores

miércoles, 30 de octubre de 2013

Conozcamos la STL (Standard Template Library) de C++ - Primera entrega: std::map - Parte 2 de 2

Introducción

Mucha personas (como yo en el pasado cercano) ignorarán el poder oculto detrás de las siglas STL. Se trata de nada más ni nada menos que una de las "cosas" que convierte a C++ en uno de los lenguajes de programación más poderosos. La STL o Standard Template Library 
La STL proporciona una colección de estructuras de datos contenedoras y algoritmos genéricos que se pueden utilizar con éstas.
Dada la extensión que pretendía dar a este tema, decidí dividirlo en dos entradas independientes y complementarias.
La primera parte de esta entrega (disponible aquí) consiste en la implementación del contenedor std::map con los tipos de datos incluidos en el estándar de C++.
En la segunda parte (este post) abordaré la implementación del contenedor std::map haciendo uso de una clase propia, es decir, una clase que hemos hecho nosotros mismos, tal como lo ilustramos en una entrega previa, donde hemos definido una clase para la manipulación de vectores.

Usando std::map con una clase propia

Supongamos ahora que creamos una clase y queremos usarla en una variable tipo std::map. Para tal fin es necesario crear un criterio de comparación, específicamente, es necesario definir el operador< dentro de nuestra clase, puesto que std::map se basa en el para realizar el ordenamiento.
En una entrega previa hemos definido una clase para la manipulación de vectores y hemos definido el operador< dentro de la misma tal como lo requiere el std::map.

La clase cVector y su código de implementación pueden descargarse usando este enlace.
Mirando el código de ejemplo:


#include <iostream>
#include <map>
#include "cVector.hpp"

int main(void)
{

    cVector I_vector;
    cVector J_vector;
    cVector K_vector;
 
/*
Aqui implementamos un mapa que contiene elementos de la clase cVector,
No debe representar problemas puesto que el operador< ha sido definido para la clase
como puede verse en cVector.hpp
*/

    std::map<int,cVector> mi_mapav;
 
    I_vector.colocarCoordenadas(1,0,0);
    J_vector.colocarCoordenadas(0,2,0);
    K_vector.colocarCoordenadas(0,0,3);

 
mi_mapav[0]=I_vector;
mi_mapav[1]=J_vector;
mi_mapav[2]=K_vector;

    std::cout << "Producto punto entre I y K " << I_vector*K_vector << std::endl;
 
    std::cout << "La magnitud de la suma vectorial entre I y J " << (I_vector+J_vector).normaVector() << std::endl;
 
    if( (I_vector+J_vector)<K_vector)
    {
std::cout << "La magnitud de I + J es menor que la de K " << std::endl;
}
else
{
std::cout << "La magnitud de I + J es mayor que la de K " << std::endl;
}

for(int i=0;i<1;i++)
{
std::cout << "Usando el std::map tenemos la norma de la suma de vectores consecutivos" << (mi_mapav[i]+mi_mapav[i+1]).normaVector() << std::endl;

}
}


lunes, 12 de agosto de 2013

Conozcamos la STL (Standard Template Library) de C++ - Primera entrega: std::map - Parte 1 de 2

Introducción

Mucha personas (como yo en el pasado cercano) ignorarán el poder oculto detrás de las siglas STL. Se trata de nada más ni nada menos que una de las "cosas" que convierte a C++ en uno de los lenguajes de programación más poderosos. La STL o Standard Template Library 
La STL proporciona una colección de estructuras de datos contenedoras y algoritmos genéricos que se pueden utilizar con éstas.
(tomado de aquí: http://decsai.ugr.es/~jfv/ed1/c++/cdrom4/paginaWeb/stl.htm)

En esta entrega trataré de ilustrar el uso del contenedor map, a través de algunos ejemplos prácticos.

Dada la extensión que pretendía dar a este tema, decidí dividirlo en dos entradas independientes y complementarias.
La primera  parte de esta entrega (es decir, este post) consiste en la implementación del contenedor std::map con los tipos de datos incluidos en el estándar de C++.

En la segunda parte (disponible aquí) abordaré la implementación del contenedor std::map haciendo uso de una clase propia, es decir, una clase que hemos hecho nosotros mismos, tal como lo ilustramos en  una entrega previa, donde hemos definido una clase para la manipulación de vectores.

Contenedor std::map de la STL

Generalidades del contenedor std::map

Uno de esos contenedores incluidos en la STL corresponde a map, un contenedor de datos donde cada uno posee una clave(key en inglés) que lo identifica. Para utilizar map es necesario incluirlo en la cabecera de nuestro código fuente:
#include<map>
De esta manera, es posible hacer el llamado
std::map<tipo_variable_1 clave,tipo_variable_2 valor, criterio_comparación_clave> variable_map;
 De esta manera, se puede declarar una varible tipo map, en este caso: variable_map. Esta definición parece un poco ambigua de entender, pero todo es más claro en cuanto se entiende que la variable map lo que hace es etiquetar con la variable clave lo que contiene la variable valor. Para realizar el ordenamiento, el contenedor map utiliza un criterio de comparación basándose en alguna operación de comparación, específicamente, usando el operador< definido para del tipo_variable_1, es por esta razón que el operador< debe estar definido para el tipo de variable utilizado como clave.
Para realizar la asignación de valores a nuestro mapa, basta con escribir
variable_map[valor_tipo_variable_1]=valor_tipo_variable_2;
Para ver claramente lo que acabo de exponer, observemos el siguiente ejemplo (código c++, obviamente)



#include<iostream>
#include<string>
#include<map>


int main(void)
{
        std::map<int /*indice o clave*/, std::string /*contenido*/> mi_mapa;

       std::string palabra;

        for(int i(0);i<5;i++)
        {
                std::cout << "Ingrese una palabra: " << std::endl;
                std::cin>>palabra;
                mi_mapa[i]=palabra;
        }


        for(i=0;i<5;i++)
        {
                std::cout << "Palabra almacenada con clave " << i << " es " << mi_mapa[i] << std::endl;
        }
}


Vemos que en el ejemplo hemos usado map como si se tratase de un array. Sin embargo, la diferencia sustancial es que la información se ha guardado de manera ordenada en función del valor de i. Este comportamiento no es visible a simple vista, puesto que el orden de entrada de los datos ya están ordenados, pero considere el siguiente ejemplo

#include<iostream>
#include<string>
#include<map>

int main(void)
{
        std::map<int /*indice o clave*/, std::string /*contenido*/> mi_mapa;
        std::string palabra;
        int numero;


        for(int i(0);i<5;i++)
        {
                std::cout << "Ingrese un número: " << std::endl;
                std::cin >> numero;

                std::cout << "Ingrese una palabra: " << std::endl;
                std::cin >> palabra;


                mi_mapa[numero]=palabra;
        }


        for(i=0;i<5;i++)
        {
                std::cout << "Palabra almacenada con clave " << i << " es " << mi_mapa[i] << std::endl;
        }

}

En este caso, vemos que para cada valor no repetido de i, se muestra un valor de palabra. es decir, que para cada int i, se ha asignado una variable std::string. Este uso sigue siento familiar con el uso de los arrays. Podemos probar cambiando los tipos de variable en la definición de la variable tipo map. Considere el siguiente ejemplo

#include<iostream>
#include<string>
#include<map>

int main(void)
{
        std::map<std::string /*indice_palabra*/,int /*indice_numero*/> mi_mapa;
        std::string palabra;
        int numero;

        mi_mapa["hola"]=10;
        mi_mapa["alfabeto"]=5;
        mi_mapa["zoo"]=0;
        mi_mapa["a"]=3;
        mi_mapa["marmota"]=9;


        std::cout << " La palabra \"alfabeto\" tiene asignado el número " << mi_mapa["alfabeto"] << std::endl;
        std::cout << " La palabra \"a\" tiene asignado el número " << mi_mapa["a"] << std::endl;

        std::cout << " La palabra \"hola\" tiene asignado el número " << mi_mapa["hola"] << std::endl;
        std::cout << " La palabra \"marmota\" tiene asignado el número " << mi_mapa["marmota"] << std::endl;



}

A cada std::string se ha asignado un valor numérico tipo int, de esta manera, los llamados a cada int se realizan mediante el std::string correspondiente a su clave.

Considere ahora el siguiente ejemplo

#include<iostream>
#include<string>
#include<map>

int main(void)
{
        std::map<std::string /*indice_palabra*/,int /*indice_numero*/> mi_mapa;
        std::string palabra;
        int numero;


        for(int i(0);i<5;i++)
        {
                std::cout << "Ingrese un número: " << std::endl;
                std::in >> numero;

                std::cout << "Ingrese una palabra: " << std::endl;
                std::in >> palabra;


                mi_mapa[palabra]=numero;
                std::cout << " La palabra << palabra << " tiene asignado el número " << mi_mapa[palabra] << std::endl;

        }

}

En este caso, a cada palabra ingresada por el usuario, se ha asignado un valor numérico también ingresado por el usuario. El ordenamiento se hace según el operador< definido en la clase std::string.

miércoles, 1 de mayo de 2013

El uso de clases y objetos en la programación científica


Esta es una de mis entradas más pretenciosas, quizá el título de esta entrada es un tanto pueril para muchos programadores experimentados.
Mi motivación para la misma es el hecho que pocas veces logra darse la preponderancia suficiente a este asunto en los cursos de programación de las carreras científicas.
Por lo general, se orienta la programación hacia el paradigma de la programación estructurada, paradigma poco elegante si se quiere trabajar en proyectos grandes o si se quiere implementar fácilmente el código fuente escrito, si queremos que otros utilicen nuestro código.

Como científico, es preciso aprovechar todas las herramientas disponibles para resolver nuestros problemas de investigación o de cualquier otra índole académica. Si bien no soy experto en programación, mi experiencia programando desde hace unos 3 años me ha permitido darme cuenta de la importancia que tiene el paradigma de la programación orientada a objetos si se quiere trabajar en el diseño de simulaciones y/o en instrumentación científica. 


Una idea de lo que es una clase


Dejando de lado los formalismos, pienso que una clase se puede definir como un tipo (abstracto) de datos (tipo de variable) más unos métodos propios de la clase (del tipo de datos) a la que pertenecen. Así, cuando se crea una clase, es posible implementarla en nuestros programas, incluir cambios y funciones den la clase y automáticamente los cambios de propagarán a los programas donde la clase se implemente. Para no dejar las cosas en el aire, pensemos en una aplicación al álgebra de vectores como un problema de programación y miremos su solución desde el punto de vista de la programación estructurada y la programación orientada a objetos.

Manipulando vectores con programación estructurada

Mediante la programación estructurada, la salida rápida para le problema se hace a través del uso de arreglos (arrays) lo cual está bien, pero es poco elegante, por ejemplo, para definir el vector i que apunta en la dirección x, puede hacerse algo como esto (código fuente C/C++)

    double i_vector[3];

    i_vector[0]=1;
    i_vector[1]=0;
    i_vector[2]=0;

Lo cual servirá, pero como dije antes, es poco elegante, para tener la base completa {i,j,k} tendríamos el siguiente lío

    double i_vector[3];
    double j_vector[3];
    double k_vector[3];

    i_vector[0]=1;
    i_vector[1]=0;
    i_vector[2]=0;

    j_vector[0]=0;
    j_vector[1]=1;
    j_vector[2]=0;

    k_vector[0]=0;
    k_vector[1]=0;
    k_vector[2]=1;

Ahora, pensemos que queremos definir un producto interno entre vectores (producto punto). Hasta ahora nuestro código solo tiene arreglos definidos, por lo tanto, necesitamos crear una función que lleve a cabo la tarea de calcular el producto punto. Por ejemplo


double productoPunto(double vector1[],double vector2[])
{
    int i=0;
    double res=0;
 
    for(i=0;i<sizeof(vector1);i++)
    {
        res = vector1[i] * vector2[i] + res;
    }
 
    return res;
}


la cual puede llamarse así
 
    punto(i_vector,k_vector)

Funciona, pero siempre queda la sensación que hace falta algo, la sensación que nuestro programa puede ser mejor. Y de hecho, es posible.


Manipulando vectores con programación orientada a objetos


Había mencionado que la programación orientada a objetos hacía uso del concepto de clase a la hora de programar, también había dicho que la clase incluye funciones. Siguiendo con nuestro problema modelo, he escrito una clase llamada cVector (el nombre lo he puesto yo), la clase sirve para manipular vectores en un espacio 3-D. La definición se da a continuación


#include<iostream>
#include<string>
#include <cmath>

class cVector
{
private:

// private quiere decir que las variables a continuación solo pueden accederse desde la clase misma
// es decir, no pueden ser modificadas al momento de implementar el codigo
// por esta razon hay que crear alguna funcion que modifique estos valores
// más adelante veremos las funciones que manipulan estas variables


// Defino una variable para cada coordenada espacial
        double coordenada_x;
        double coordenada_y;
        double coordenada_z;

public:

// public quiere decir que todo lo que se defina a continuacion puede ser accedido al momento de
// implementar la clase

// esta funcion se encarga de modificar las variables privadas de coordenadas

        void colocarCoordenadas(double dX,double dY, double dZ);

// esta funcion retorna la norma del vector
        double normaVector();



// esta funcion permite la igualacion de vectores, es decir, tener por ejemplo vector_a y vector_b
// y hacer que vector_b contenga lo mismo que vector_a solo con hacer
// vector_b=vector_a;
// este proceso se conoce como "sobrecarga de operadores" y consiste en definir las operaciones
// para los operadores de uso común, en este caso, el operador de asignación

        cVector& operator= ( const cVector &rhs );

// esta sobrecarga del operador <, calcula las normas de los vectores y nos dice cual tiene una norma mayor
        bool operator< ( const cVector& other) const;

//con esta sobrecarga implementamos el producto punto entre vectores
        double operator*( const cVector& other ) const;

// con esta sobrecarga se implementa la suma de vectores
        cVector&  operator+(const cVector &other);

};


// Luego de haber declarado la clase y sus funciones, se debe colocar el código de la implementacion de las // funciones, es decir, lo que hacen
void cVector::colocarCoordenadas(double dX,double dY, double dZ)
{
        coordenada_x=dX;
        coordenada_y=dY;
        coordenada_z=dZ;
}


double cVector::normaVector()
{
         return sqrt( coordenada_x*coordenada_x + coordenada_y*coordenada_y + coordenada_z*coordenada_z);
}


cVector& cVector::operator= ( const cVector &rhs )
{

 if ( this == &rhs )    //Verifico si se trata del mismo objeto
    {
      return *this;
    }
  else
    {

        coordenada_x=rhs.coordenada_x;
        coordenada_y=rhs.coordenada_y;
        coordenada_z=rhs.coordenada_z;


        return *this;
    }

}

bool cVector::operator< ( const cVector& other) const
{
    return  ( sqrt( coordenada_x*coordenada_x + coordenada_y*coordenada_y + coordenada_z*coordenada_z) < sqrt( other.coordenada_x*other.coordenada_x + other.coordenada_y*other.coordenada_y + other.coordenada_z*other.coordenada_z) );
}

double cVector::operator*(const cVector &other) const
{
    return coordenada_x*other.coordenada_x + coordenada_y*other.coordenada_y + coordenada_z*other.coordenada_z;
}

cVector&  cVector::operator+(const cVector &other) //const
{
     coordenada_x+=other.coordenada_x;
     coordenada_y+=other.coordenada_y;
     coordenada_z+=other.coordenada_z;
   
     return *this;
}

A la hora de utilizar esta clase, basta con incluirla en los archivos de cabecera y utilizar cada una de sus funciones fácilmente

#include "cVector.hpp"

int main(void)
{
    cVector I_vector;
    cVector J_vector;
    cVector K_vector;

    I_vector.colocarCoordenadas(1,0,0);
    J_vector.colocarCoordenadas(0,1,0);
    K_vector.colocarCoordenadas(0,0,1);

    std::cout << "El producto punto entre I y K es = " <<  I_vector*K_vector  << std::endl;
    std::cout << "La magnitud de la suma vectorial entre I y J " << (I_vector+J_vector).normaVector() << std::endl;
 
//vemos como la suma de vectores se incorpora fácilmente
    if( (I_vector+J_vector)<K_vector)
    {
std::cout << "La magnitud de I + J es menor que la de K " << std::endl;
}
else
{
std::cout << "La magnitud de I + J es mayor que la de K " << std::endl;
}

}

La elaboración de la clase nos permite un control mayor de todas las cosas que pasan con nuestras variables, a la hora de implementar la clase, todo el código detrás de las funciones queda "oculto" pudiéndonos concentrar más en como aprovechar la clase y no en como encajar nuestro problema en la programación estructurada.

La clase cVector y su código de implementación pueden descargarse usando este enlace

lunes, 4 de marzo de 2013

C/C++ Pointers and functions


pointer is a powerful tool when you're programming. It's very common to be confused by the use of pointers on programming languages such as C or C++. On a very basic level, a pointer stores the memory address of a variable

Wait... you said "memory address"?
The concept of pointer it's strongly linked to the concept of memory adress so we need to make clear few things first. Let's say that a program is a collection of variables and functions. Every time that your program runs, the computer assigns it a portion of memory for each variable it creates. The size of each the memory block depends on the type of the variable, in order to get the computer working and do not mistake variables between processes (running programs), each memory block is endowed with a memory address. A memory address is a number (an unsigned int, but also has hexadecimal representation, and a physical place where the information it's saved, the information must be physically somewhere!, but that's another story). Said that, let say that a pointer is a special type of variable that stores a memory address.


Creating a pointer
Each pointer must be declared using the type of the variable which stores its memory address, so, for store the address of a double variable, we must have a pointer of type double
double variable;
double *variable_pointer;
variable_pointer=&variable;

So "variable_pointer" stores the address of "variable". An assignation as

int variable;
double *variable_pointer;
variable_pointer=&variable;
Would lead to error in execution/compilation process as a result of type mismatch

Let's see some examples on C code

In C/C++, the adress of a variable can be obtained by using the ampersand operator, that is, &.
When you make an statement like
&variable
What you actually get is the memory adress of  "variable". This can be more clear by the next example code:
#include <stdio.h>
#include <stdlib.h>

int by_pointer(int *i)
{
    printf("\nVariable value passed \'by pointer\' : %d \n",*i);
    printf("Memory adress : %X \n\n",&*i);
    return *i;
}
int by_value(int j)
{
    printf("\nVariable value passed \'by value\' : %d \n",j);
    printf("Memory adress : %X \n\n",&j);
    return j;
int main(void)
{
     int y;
     printf("Write an integer number\?\n");
     scanf("%d",&y);
     by_value(y);
     by_pointer(&y);
     printf("Variable initial address %X \n\n",&y);
}
I've compiled that code, an then ran the program and the output was
Write an integer number?
3
Variable value passed 'by value' : 3
Memory adress : C42DC23C

Variable value passed 'by pointer' : 3
Memory adress : C42DC25C

Variable initial address C42DC25C 
As you see, when the variable it's created, takes the address (in this particular example. The addresses change each programm run) "C42DC25C". When you pass the y variable to by_value(), another variable is created, that's why the address "C42DC23C" is shown (instead of "C42DC25C" which is the original memory address ). When we call the function by_pointer(&y) passing y's address, we see that the functions returns exactly the same address as "y", so it don't creates a new varible. The function uses the existing variable, so memory is saved.

You can use pointers to modify the value of an external variable by passing the argument using pointers. Let me show you an example code:
#include <stdio.h>
#include <stdlib.h>

void modify_by_pointer(int *i)
{
    printf("Write an integer number\?\n");
    scanf("%d",&*i);
}

int main(void)
{
    int y;
    modify_by_pointer(&y);
    printf("\nThe value of y is %d\n",y);
}
So, when you run the program, you can get a result like

Write an integer number?
4
The value of y is 4
That's cuz, passing the direcction to the function, it modifies the variable itself, instead of creating a copy of it,. When you use pointers to pass arguments to functions, it's known as pass by reference, that's how you will find on the literature