Matlab from Fortran - problems transferring big matrix

Viewed 79

I have to call Matlab from Fortran and execute a program there. I have a large 3xN (N is around 2500) matrix of data, which needs to be transferred to Matlab. I noticed some discrepancies in the data - the last line of the Fortran matrix becomes first line in Matlab (other lines stay however on their place, shifted down by 1), and this line also looses the first value.

Like this - In Fortran

1.1 1.2 1.3
2.1 2.2 2.3
.....
1999.1 1999.2 1999.3
2000.1 2000.2 2000.3 

becomes in Matlab

0.0 2000.2 2000.3
1.1 1.2 1.3
2.1 2.2 2.3
.....
1999.1 1999.2 1999.3

I cant understand what is going wrong somehow.. Spent several hours...

node_xyz_ini = mxCreateDoubleMatrix(M, N, 0) ! M, N - dimensions
call mxCopyReal8ToPtr(CoordSet, mxGetPr(node_xyz_ini), M*N)
1 Answers

I use Octave rather than matlab. With that as a caveat, here is an example of what I use, this for double precision twod arrays:

MODULE IO
  use, intrinsic :: iso_c_binding
  !! use c_float,c_double, c_double_complex, c_int,c_ptr
  implicit none
  real (c_double), allocatable :: x(:,:),h(:),f(:)
  integer (c_int),allocatable :: t(:,:)
  integer (c_int) :: nx,ne
contains


  Subroutine Write_Array_RDP(varname,variable)
    implicit none
    integer (c_int) :: kx,ky,sh(2),ncol,nrow
    character(len=7),intent(in) :: varname
    character(:),allocatable :: wrtfmt
    character(range(ncol)) :: res
    real(c_double),intent(in) :: variable(:,:)
    open(unit=10,file=varname,form="formatted",status="replace",action="write")
    write(10,fmt="(A)")"# created by ?? "
    sh=shape(variable)
    ncol=sh(2);nrow=sh(1)
    write(10,fmt="(A,A)")"# name: ",varname
    write(10,fmt="(A)")"# type: matrix"
    write(10,fmt="(A,i0)")"# rows: ",nrow
    write(10,fmt="(A,i0)")"# columns: ",ncol
    write(res,'(i0)') ncol
    wrtfmt="("//trim(res)//"(e20.12))"
    do ky=1,nrow
       write(10,fmt=wrtfmt)(variable(ky,kx),kx=1,ncol)
    end do
    write(10,*)" "
    write(10,*)" "
    close(10)
  End Subroutine Write_Array_RDP

END MODULE IO

Program Main
  use IO
  implicit none
  real (c_double),allocatable :: DPArray(:,:)
  allocate(DPArray(3,3))
DPArray=reshape((/1.0d0,2.0d0,3.0d0,1.0d0,2.0d0,3.0d0,1.0d0,2.0d0,3.0d0/),(/3,3/))
  Call Write_Array_RDP('DPArray',DPArray)
End Program Main

I compile and link with 'gfortran name.f90' then run with ./a.out. The file DPArray has been created. Then in Octave :

load DPArray
DPArray

produces the output:

1   1   1
2   2   2
3   3   3

I have found it necessary to recode the Write subroutine for different variable types (Write_Array_CMPLX, Write_Array_INT) etc...

Related