Open main menu

Difference between revisions of "Fortran"

(Created page with " {{Code|C++ function to load a matrix from an ASCII file in Octave native format|<syntaxhighlight lang="C" style="font-size:13px"> #include <octave_file_io.h> #include <oct...")
 
(fix name of fortran file)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
This page describes an example of how to call liboctave functions from a Fortran program.
 +
In the example we will load an Octave array from a file in Octave's native ASCII format,
 +
it consists of two steps:
  
 +
* write a C++ function with a C compatible interface and C linkage that reads a variable from an Octave ASCII file
 +
* write Fortran code using the "iso_c_binding" intrinsic module to call the C++ function
  
{{Code|C++ function to load a matrix from an ASCII file in Octave native format|<syntaxhighlight lang="C" style="font-size:13px">
+
=== C++ function ===
 +
 
 +
{{Code|octave_file_io.cc: C++ function to load a matrix from an ASCII file in Octave native format|<syntaxhighlight lang="C" style="font-size:13px">
 
#include <octave_file_io.h>
 
#include <octave_file_io.h>
  
Line 41: Line 48:
 
   *data = (double*) malloc (M.numel () * sizeof (double));
 
   *data = (double*) malloc (M.numel () * sizeof (double));
 
   *numel = M.numel ();
 
   *numel = M.numel ();
  std::cout << M << std::endl << *numel << std::endl;
+
 
 
   memcpy (*data, M.fortran_vec (), *numel * sizeof (double));
 
   memcpy (*data, M.fortran_vec (), *numel * sizeof (double));
  
Line 49: Line 56:
  
  
{{Code|C interface to a function linking to liboctave|<syntaxhighlight lang="C" style="font-size:13px">
+
=== Header file ===
 +
 
 +
{{Code|octave_file_io.h: header file with C interface to octave_file_io.cc|<syntaxhighlight lang="C" style="font-size:13px">
 
#ifndef OCTAVE_FILE_IO_H
 
#ifndef OCTAVE_FILE_IO_H
 
#define OCTAVE_FILE_IO_H
 
#define OCTAVE_FILE_IO_H
Line 65: Line 74:
 
#endif
 
#endif
 
</syntaxhighlight>}}
 
</syntaxhighlight>}}
 +
 +
 +
=== Fortran Code ===
 +
 +
{{Code|octave_file_io_example.f90|<syntaxhighlight lang="fortran" style="font-size:13px">
 +
program octave_file_io_example
 +
 
 +
  use iso_c_binding
 +
   
 +
  implicit none
 +
 +
  interface
 +
    function octave_load (filename, varname, data, numel) bind(c, name="octave_load")
 +
     
 +
      use iso_c_binding
 +
      implicit none
 +
 +
      integer(c_int) :: octave_load
 +
     
 +
      character(kind=c_char), intent(in) :: filename(*)
 +
      character(kind=c_char), intent(in) :: varname(*)
 +
     
 +
      type(c_ptr), intent(out) :: data
 +
      integer(c_int), intent(out) :: numel
 +
     
 +
    end function octave_load
 +
  end interface
 +
 
 +
  integer(c_int) :: res
 +
  type(c_ptr) :: data
 +
  real(c_double), pointer :: fdata(:)
 +
  integer(c_int) :: numel
 +
 +
  res = octave_load (c_char_'pippo.octxt' // c_null_char, c_char_'A' // c_null_char, data, numel)
 +
 
 +
  call c_f_pointer (data, fdata, (/numel/))
 +
 
 +
  write (*,*) fdata
 +
 +
end program octave_file_io_example
 +
</syntaxhighlight>}}
 +
 +
 +
 +
 +
=== Compiling the code ===
 +
 +
  mkoctfile -I. octave_file_io.cc
 +
  mkoctfile -I. --mkoctfile --link-stand-alone octave_file_io_example.f90 octave_file_io.o -o octave_file_io_example
 +
 +
[[Category:Examples]]

Latest revision as of 15:39, 22 March 2014

This page describes an example of how to call liboctave functions from a Fortran program. In the example we will load an Octave array from a file in Octave's native ASCII format, it consists of two steps:

  • write a C++ function with a C compatible interface and C linkage that reads a variable from an Octave ASCII file
  • write Fortran code using the "iso_c_binding" intrinsic module to call the C++ function

Contents

C++ functionEdit

Code: octave_file_io.cc: C++ function to load a matrix from an ASCII file in Octave native format
#include <octave_file_io.h>


#include <octave/oct.h>
#include <octave/ov.h>
#include <fstream>
#include <ls-oct-ascii.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h>
#include <octave/load-save.h>
#include <octave/oct-map.h>
#include <cstring>

int octave_load (const char* filename, const char* varname, double** data, int* numel)
{
  
  string_vector argv (1);
  load_save_format format = LS_ASCII;

  install_types ();  
  argv(0) = varname;
  
  std::ios::openmode mode = std::ios::in | std::ios::binary;
  std::string fname (filename);

  std::ifstream file (fname.c_str (), mode);
  
  octave_scalar_map m = do_load (file, fname, format, oct_mach_info::flt_fmt_unknown,
                                 false, false, true, argv, 0, 1, 1).scalar_map_value ();

  file.close ();  

  Array<double> M = m.contents (varname).array_value ();
  if (error_state)
    return -1;

  *data = (double*) malloc (M.numel () * sizeof (double));
  *numel = M.numel ();

  memcpy (*data, M.fortran_vec (), *numel * sizeof (double));

  return 0;  
}


Header fileEdit

Code: octave_file_io.h: header file with C interface to octave_file_io.cc
#ifndef OCTAVE_FILE_IO_H
#define OCTAVE_FILE_IO_H

#ifdef __cplusplus
extern "C" {
#endif
  
  int octave_load (const char* filename, const char* varname, double** data, int* numel);

#ifdef __cplusplus
}
#endif

#endif


Fortran CodeEdit

Code: octave_file_io_example.f90
program octave_file_io_example
  
  use iso_c_binding
    
  implicit none

  interface 
     function octave_load (filename, varname, data, numel) bind(c, name="octave_load")
       
       use iso_c_binding
       implicit none

       integer(c_int) :: octave_load
       
       character(kind=c_char), intent(in) :: filename(*)
       character(kind=c_char), intent(in) :: varname(*)
       
       type(c_ptr), intent(out) :: data
       integer(c_int), intent(out) :: numel
       
     end function octave_load
  end interface
  
  integer(c_int) :: res 
  type(c_ptr) :: data
  real(c_double), pointer :: fdata(:)
  integer(c_int) :: numel

  res = octave_load (c_char_'pippo.octxt' // c_null_char, c_char_'A' // c_null_char, data, numel)
  
  call c_f_pointer (data, fdata, (/numel/))
  
  write (*,*) fdata

end program octave_file_io_example



Compiling the codeEdit

 mkoctfile -I. octave_file_io.cc 
 mkoctfile -I. --mkoctfile --link-stand-alone octave_file_io_example.f90 octave_file_io.o -o octave_file_io_example