Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

operators for matrix


Dear all,

I am writeing a program which will contain many matrix manipulations.
I want to define my own operators to shorten the syntax for the matrix
manipulations. Below is a small program as example.

This program run fine using g95.

Using the ifort 9.1 compiler give error:
Syntax error, found '.' when expecting one of: ( , <END-OF-STATEMENT> ;
<IDENTIFIER> <CHAR_CON_KIND_PARAM> <CHAR_NAM_KIND_PARAM> ...
write(*,*) .t.(a.mm..ms.(Im+(.ms.btot).mm.s)) After commenting out this
line it runs fine.

The gfortran compiler warns:
matrixmantst.f90: In function vectorskew:
matrixmantst.f90:55: warning: Function does not return a value
matrixmantst.f90: In function matrixskew:
matrixmantst.f90:47: warning: Function does not return a value
and gives a segmentation fault when it is run.  If I changes:
  call skewmatrix(MatrixSkew,vec1(:,1))
by:
  real(dp) :: tmm(3,3)
  call skewmatrix(tmm,vec1(:,1))
  MatrixSkew = tmm
  (same for VectorSkew)
it runs fine without runtime checks, with runtime check it gives still
a segmentation fault

The Sun f95 compiler gives error:
public operator(.mm.),operator(.t.),operator(.ms.), skewmatrix
                               ^
"matrixmantst.f90", Line = 10, Column = 32: ERROR: A defined operator
must not be the same as a logical literal constant. After changing t by
tt it runs fine.

The PGI compiler gives:
PGF90-S-0034-Syntax error at or near ) (matrixmantst.f90: 102)
PGF90-S-0034-Syntax error at or near ) (matrixmantst.f90: 108)
By adding additional parentheses (.t.(a.mm.(.ms.(Im+(.ms.btot).mm.s))))
this error was is resolved and the program runs fine.

My questions are: Is this code according the F95 standards? Have you
any suggestions/comments how I can improve this code. Especially, how
can this be done so it will work for every F95 compiler?

Thanks in advance,

Johan

module types
! select kind
integer, parameter :: dp=kind(0.d0)
end module

module matrixman
! module for short matrix syntax
private

public operator(.mm.),operator(.t.),operator(.ms.), skewmatrix

interface operator (.mm.)
  module procedure MatrixMultiplication
end interface

interface operator (.t.)
  module procedure MatrixTranspose
end interface

interface operator (.ms.)
  module procedure MatrixSkew
  module procedure VectorSkew
end interface

contains
 function MatrixMultiplication(mat1,mat2)
  use types
  implicit none
  real(dp), intent(in) :: mat1(:,:), mat2(:,:)
  real(dp) :: MatrixMultiplication(size(mat1,dim=1),size(mat2,dim=2))
  MatrixMultiplication = matmul(mat1,mat2)
 end function

 function MatrixTranspose(mat1)
  use types
  implicit none
  real(dp), intent(in) :: mat1(:,:)
  real(dp) :: MatrixTranspose(size(mat1,dim=2),size(mat1,dim=1))
  MatrixTranspose = transpose(mat1)
 end function

 function MatrixSkew(vec1)
  use types
  implicit none
  real(dp), intent(in) :: vec1(3,1)
  real(dp) :: MatrixSkew(3,3)
  call skewmatrix(MatrixSkew,vec1(:,1))
 end function

 function VectorSkew(vec1)
  use types
  implicit none
  real(dp), intent(in) :: vec1(3)
  real(dp) :: VectorSkew(3,3)
  call skewmatrix(VectorSkew,vec1)
 end function

 subroutine skewmatrix(SMat,s)
  use types
  implicit none

  real(dp), intent(in) :: s(3)
  real(dp), intent(out) :: SMat(3,3)

  SMat(1,1) = 0.0_dp
  SMat(1,2) = -s(3)
  SMat(1,3) =  s(2)

  SMat(2,1) =  s(3)
  SMat(2,2) = 0.0_dp
  SMat(2,3) = -s(1)

  SMat(3,1) = -s(2)
  SMat(3,2) =  s(1)
  SMat(3,3) = 0.0_dp
 end subroutine
end module

program matrixtst
use types
use matrixman
implicit none
real(dp) :: res1(3,3), a(3,3), Im(3,3), btot(3,1), s(3,1)
real(dp) :: res2(3,3), bk(3,3), w1(3,1)

! filling the matrix with random numbers
call random_seed()
call random_number(a)
call random_number(Im)
call random_number(btot)
call random_number(s)

! original code
call skewmatrix(bk,btot)
bk = bk + Im
w1 = matmul(bk,s)
call skewmatrix(bk,w1)
res1 = transpose(matmul(a,bk))

! short code which should be equivalent
res2 =   .t.(a.mm..ms.(Im+(.ms.btot).mm.s))

write(*,*) res1
write(*,*)
write(*,*) res2
write(*,*)
write(*,*) .t.(a.mm..ms.(Im+(.ms.btot).mm.s))

end program

"Johan" <j@notused.invalid> wrote in message

news:20070514182541.26aec236@reken.site...

This program runs fine using g95.

       Indeed.

Using the ifort 9.1 compiler give error:
Syntax error, found '.' when expecting one of: ( , <END-OF-STATEMENT> ;
<IDENTIFIER> <CHAR_CON_KIND_PARAM> <CHAR_NAM_KIND_PARAM> ...
write(*,*) .t.(a.mm..ms.(Im+(.ms.btot).mm.s)) After commenting out this
line it runs fine.

    The CVF compiler also doesn't like this but accepts the expression in
parentheses. The code is correct

The gfortran compiler warns:
matrixmantst.f90: In function 'vectorskew':
matrixmantst.f90:55: warning: Function does not return a value
matrixmantst.f90: In function 'matrixskew':
matrixmantst.f90:47: warning: Function does not return a value
and gives a segmentation fault when it is run.  If I changes:
  call skewmatrix(MatrixSkew,vec1(:,1))
by:
  real(dp) :: tmm(3,3)
  call skewmatrix(tmm,vec1(:,1))
  MatrixSkew = tmm
  (same for VectorSkew)
it runs fine without runtime checks, with runtime check it gives still
a segmentation fault

      gfortran is not checking properly. The code is correct.

The Sun f95 compiler gives error:
public operator(.mm.),operator(.t.),operator(.ms.), skewmatrix
                               ^
"matrixmantst.f90", Line = 10, Column = 32: ERROR: A defined operator
must not be the same as a logical literal constant. After changing t by
tt it runs fine.

     Some compilers accept .t. for .true. as an extension. As you may not
use .true. as an operator so, by extension, .t. becomes forbidden. A
compiler error, especially if running with standards checks on.

The PGI compiler gives:
PGF90-S-0034-Syntax error at or near ) (matrixmantst.f90: 102)
PGF90-S-0034-Syntax error at or near ) (matrixmantst.f90: 108)
By adding additional parentheses (.t.(a.mm.(.ms.(Im+(.ms.btot).mm.s))))
this error was is resolved and the program runs fine.

      See above.

Your code is correct, IMHO, and you have found some wonderful compiler bugs.

Regards,

Mike Metcalf

Operator overloading aside, gfortran has a problem with an array-
valued function result when the result is passed to a procedure but
the result syntax is not used in declaring the function. This is
demonstrated by the following program, which has been submitted to
bugzilla http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31921 .

module mman
implicit none
private
public mskew,nskew
contains
function nskew() result(y)
real :: y(1)
call skewm(y)
end function nskew
!
function mskew()
real :: mskew(1)
call skewm(mskew)
end function mskew
!
subroutine skewm(smat)
real, intent(out) :: smat(1)
smat = 0.0
end subroutine skewm
end module mman
!
program mtst
use mman, only: mskew,nskew
implicit none
print*,"(1) calling nskew"
print*,nskew()
print*,"(2) calling mskew"
print*,mskew()
print*,"(3) done"
end program mtst

Compiling with mingw gfortran 20070506 with the default options gives
the
incorrect warning message

xfunc_bug.f90: In function 'mskew':
xfunc_bug.f90:13: warning: Function does not return a value

and at run time the output is

 (1) calling nskew
   0.000000
 (2) calling mskew

<crash>

On May 14, 2:06 pm, Beliavsky <beliav@aol.com> wrote:

> Operator overloading aside, gfortran has a problem with an array-
> valued function result when the result is passed to a procedure but
> the result syntax is not used in declaring the function. This is
> demonstrated by the following program, which has been submitted to
> bugzillahttp://gcc.gnu.org/bugzilla/show_bug.cgi?id=31921.

Follow ups by gfortran developers in bugzilla say that the problem was
fixed on May 8. No Windows binary since that date is available
(binaries are created about monthly). Could someone with a very recent
gfortran build check the code of the OP?

> Follow ups by gfortran developers in bugzilla say that the problem was
> fixed on May 8. No Windows binary since that date is available
> (binaries are created about monthly). Could someone with a very recent
> gfortran build check the code of the OP?

Today's svn build of gfortran works fine.

Victor.

In article <20070514182541.26aec@reken.site>, Johan wrote:
> I am writeing a program which will contain many matrix manipulations.
> I want to define my own operators to shorten the syntax for the matrix
> manipulations.

http://www.cs.umd.edu/~stewart/matran/Matran.html

--
Janne Blomqvist

On Tue, 15 May 2007 09:57:59 +0300 (EEST)

Janne Blomqvist <f@bar.invalid> wrote:
> In article <20070514182541.26aec@reken.site>, Johan wrote:
> > I am writeing a program which will contain many matrix
> > manipulations. I want to define my own operators to shorten the
> > syntax for the matrix manipulations.

> http://www.cs.umd.edu/~stewart/matran/Matran.html

Thanks for this link, this is very useful.

Micheal, beliavsky and Victor thanks for your responce. Now I know it
was valid Fortran.

Best regards,

Johan

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc