Wednesday, November 24, 2010

Catenary

The catenary is the curve that is naturally formed when a chain of constant linear density hangs from two fixed points. This is a typical example on variational calculus showing the use of Lagrange multipliers. Next, I develop the problem entirely in Mathematica

Catenary
Catenary(pdf)

You may need MathematicaPlayer if you do not have Mathematica.

This problem can be generalized to find the surface with minimum energy, which is shown next


MathLink Example 2: Sum a list of floating point numbers

This example considers a sum of of floating point numbers.
----------------------------------------------------------------
addRealList.c
----------------------------------------------------------------

#include "mathlink.h"
extern double addRealList( void );



double addRealList( void )
{
 int i,n;

 double *list; 

 MLGetReal64List(stdlink,&list,&n);

 double sum=0;
 for(i=0;i<n;i++) sum = sum + list[i];

 
  MLReleaseReal64List(stdlink,list,n);

 return sum;
}



#if WINDOWS_MATHLINK

#if __BORLANDC__
#pragma argsused
#endif

int PASCAL WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{

 char  buff[512];
 char FAR * buff_start = buff;

 char FAR * argv[32];
 char FAR * FAR * argv_end = argv + 32;

 hinstPrevious = hinstPrevious; /* suppress warning */

 if( !MLInitializeIcon( hinstCurrent, nCmdShow)) return 1;

 MLScanString( argv, &argv_end, &lpszCmdLine, &buff_start);
 return MLMain( (int)(argv_end - argv), argv);
}

#else

int main(int argc, char* argv[])
{

 return MLMain(argc, argv);
}

#endif


------------------------------------------------------
addRealList.tm
------------------------------------------------------

:Begin:
:Function:       addRealList

:Pattern:        addRealList[ L:{___Real}]
:Arguments:      { L  }
:ArgumentTypes:  { Manual  }
:ReturnType:     Real

:End:

:Evaluate: addRealList::usage = "addRealList[x] gives the sum of the elements on x, given that they are real (double floating numbers)"

------------------------------------------
Makefile
------------------------------------------
MPREP = /usr/bin/mprep
CXX = /usr/bin/c++

addRealList : addRealListtm.c
 ${CXX} addRealListtm.c addRealList.c -o addRealList -lML64i3 -lm -lpthread -lrt -lstdc++

addRealListtm.c : addRealList.tm
 ${MPREP} addRealList.tm -o $@

clean:

 rm addRealListtm.c
 rm addRealList
 

--------------------------------------------------------
addRealList.nb
--------------------------------------------------------

link = Install["./addRealList"]

?addRealList

addRealList[{1., 5., 6.}]

Tuesday, November 23, 2010

MathLink Example 1: Sum a List of Integers

This example passes a list of integers, performs the sum and returns an integer.
We must note that the length of the list is not type int but type long.

-------------------------------------------------------------------------
addList.c
-------------------------------------------------------------------------

#include "mathlink.h"
extern double addList( double *list, long n);



double addList( double *list, long n)
{

 int i;
 double sum=0;
 for(i=0;i<n;i++) sum = sum + list[i];

 
 return sum;
}



#if WINDOWS_MATHLINK

#if __BORLANDC__
#pragma argsused
#endif

int PASCAL WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{

 char  buff[512];
 char FAR * buff_start = buff;

 char FAR * argv[32];
 char FAR * FAR * argv_end = argv + 32;

 hinstPrevious = hinstPrevious; /* suppress warning */

 if( !MLInitializeIcon( hinstCurrent, nCmdShow)) return 1;

 MLScanString( argv, &argv_end, &lpszCmdLine, &buff_start);
 return MLMain( (int)(argv_end - argv), argv);
}

#else

int main(int argc, char* argv[])
{

 return MLMain(argc, argv);
}

#endif


---------------------------------------------------------------------
 addList.tm
---------------------------------------------------------------------
:Begin:
:Function:       addList

:Pattern:        addList[ L_List]
:Arguments:      { L  }
:ArgumentTypes:  { RealList  }
:ReturnType:     Real

:End:

:Evaluate: addList::usage = "addList[x] gives the sum of the elements of the list x"

---------------------------------------------------------------------
Makefile
---------------------------------------------------------------------
MPREP = /usr/bin/mprep
CXX = /usr/bin/c++

BINARIES = addList

all : $(BINARIES)

addList : addListtm.c addList.c
 ${CXX}  addList.c addListtm.c  -lML64i3 -lm -lpthread -lrt -lstdc++ -o $@

addListtm.c : addList.tm
 ${MPREP} addList.tm -o addListtm.c

-------------------------------------------
addList.nb
-------------------------------------------

link = Install["./addList"]

addList[{1, 5, 6}]

Monday, November 22, 2010

MathLink Example 0

MathLink is a protocol on how to communicate Mathematica with external programs. For example, one would like to run compiled code in C within the Mathematica environment.  I am going to post a sequence of MathLink programs for Linux with an increasing level of complexity, starting from a simple example already found in the Mathematica help (included for completeness) finishing with an example where I send and receive a matrix of complex numbers processed by the GPU using CUDA

Most examples are made of 4 files:
  • *.c             : where the computation occurs.
  • *.tm          : MathLink template where the input and output are specified and the documentation of the function is placed. 
  • Makefile   : where the compilation sequence is specified
  • *.nb          : Mathematica notebook that executes the whole program
These files have to be placed in the same folder and compiled with: $make , which may need editing in order to provide the path of the executable file mprep that comes as part of Mathematica. 
  
As seen in Makefile, mprep generates a proper *.c code from the *.tm file, which is compiled along with the *.c file that contains the computational process.

The first example adds two integers

---------------------------------------------------------------------------------
addtwo.c
---------------------------------------------------------------------------------


#include "mathlink.h"
extern int addtwo( int i, int j);



int addtwo( int i, int j)
{

 return i+j;
}



#if WINDOWS_MATHLINK

#if __BORLANDC__
#pragma argsused
#endif

int PASCAL WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{

 char  buff[512];
 char FAR * buff_start = buff;

 char FAR * argv[32];
 char FAR * FAR * argv_end = argv + 32;

 hinstPrevious = hinstPrevious; /* suppress warning */

 if( !MLInitializeIcon( hinstCurrent, nCmdShow)) return 1;

 MLScanString( argv, &argv_end, &lpszCmdLine, &buff_start);
 return MLMain( (int)(argv_end - argv), argv);
}

#else

int main(int argc, char* argv[])
{

 return MLMain(argc, argv);
}

#endif

-----------------------------------------------------------------
 addtwo.tm
-----------------------------------------------------------------

int addtwo P(( int, int));

:Begin:
:Function:       addtwo

:Pattern:        AddTwo[i_Integer, j_Integer]
:Arguments:      { i, j }
:ArgumentTypes:  { Integer, Integer }
:ReturnType:     Integer

:End:

:Evaluate: AddTwo::usage = "AddTwo[x, y] gives the sum of two machine integers x and y."

------------------------------------------------------------
Makefile
------------------------------------------------------------

MPREP = /usr/bin/mprep
CXX = /usr/bin/c++

BINARIES = addtwo

all : $(BINARIES)

addtwo : addtwotm.c addtwo.c
 ${CXX}  addtwotm.c addtwo.c  -lML64i3 -lm -lpthread -lrt -lstdc++ -o $@

addtwotm.c : addtwo.tm
 ${MPREP} addtwo.tm -o addtwotm.c

------------------------------------------------
addtwo.nb
------------------------------------------------
SetDirectory["/home/rcabrera/Documents/source/mathematica/MathLinkExamples/mytest2/alternative"]

link = Install["./addtwo"]

?AddTwo

AddTwo[2, 3]