Fortran coding for the density of states of linear lattice - fortran

The written code contains some errors. I am using Visual Studio 2012 and the Intel.Visual.Fortran.Composer.XE.2013.0.089 compiler.
This is the code I wrote
PROGRAM DensityOfState
IMPLICIT NONE
INTEGER :: omega , t0 , a0 ,kx
omega=1 ; t0 =1 ; a0=1
REAL :: kx , eta , w , ek
eta=0.0015
REAL,PARAMETER :: pi=3.14
COMPLEX , PARAMETER ::i=(0,1)
COMPLEX :: Energy
COMPLEX :: Density
COMPLEX :: GreenFunc
LoopEnergy : DO w=-2,+2,0.001
WRITE(*,*) Energy= w +( i * eta)
LoopWaveVector : DO kx=-1000,1000
WRITE(*,*) ek= 2*t0*COS(kx*a0)
WRITE(*,*) GreenFunc= Energy - ek
END DO LoopEnergy
END DO LoopWaveVector
WRITE(*,*) IMAG(GreenFunc)
Density= (1.0/pi*omega)*IMAG(GreenFunc)
WRITE(*,*) Density
END PROGRAM DensityOfState
And this is a list of errors
Error 1 error #5082: Syntax error, found IDENTIFIER 'ENERGY' when expecting one of: ( % [ . =
1>------ Build started: Project: Console3, Configuration: Debug Win32 ------
1>Compiling with Intel(R) Visual Fortran Compiler XE 13.0.0.089 [IA-32]...
1>Source1.f90
error #5082: Syntax error, found IDENTIFIER 'ENERGY' when expecting one of: ( % [ . = =>
error #5082: Syntax error, found IDENTIFIER 'EK' when expecting one of: ( % [ . = =>
error #5082: Syntax error, found IDENTIFIER 'GREENFUNC' when expecting one of: ( % [ . = =>
error #6236: A specification statement cannot appear in the executable section.
error #6236: A specification statement cannot appear in the executable section.
error #6236: A specification statement cannot appear in the executable section.
error #6236: A specification statement cannot appear in the executable section.
error #6236: A specification statement cannot appear in the executable section.
error #6236: A specification statement cannot appear in the executable section.
error #6404: This name does not have a type, and must have an explicit type. [ETA]
error #6404: This name does not have a type, and must have an explicit type. [W]
error #6063: An INTEGER or REAL data type is required in this context. [W]
warning #6041: The increment in a DO is zero or evaluates to zero. [0.001]
error #6458: This name must be the name of a variable with a derived type (structure type) [WRITE]
error #6404: This name does not have a type, and must have an explicit type. [I]
error #6458: This name must be the name of a variable with a derived type (structure type) [WRITE]
warning #7319: This argument's data type is incompatible with this intrinsic procedure; procedure assumed EXTERNAL. [COS]
1 error #6404: This name does not have a type, and must have an explicit type. [COS]
error #6458: This name must be the name of a variable with a derived type (structure type) [WRITE]
error #6404: This name does not have a type, and must have an explicit type. [ENERGY]
error #6404: This name does not have a type, and must have an explicit type. [EK]
error #6606: The block construct names must match, and they do not. [LOOPENERGY]
error #6606: The block construct names must match, and they do not. [LOOPWAVEVECTOR]
error #6404: This name does not have a type, and must have an explicit type. [GREENFUNC]
warning #7319: This argument's data type is incompatible with this intrinsic procedure; procedure assumed EXTERNAL. [IMAG]
error #6404: This name does not have a type, and must have an explicit type. [IMAG]
error #6404: This name does not have a type, and must have an explicit type. [DENSITY]
error #6404: This name does not have a type, and must have an explicit type. [PI]
1>compilation aborted for c:\users\mahdi\documents\visual studio 2012\Projects\Console3\Console3\Source1.f90 (code 1)

WRITE(*,*) Energy= w +( i * eta)
is not a correct Fortran statement. To assign w +( i * eta) to Energy, use just
Energy= w +( i * eta)
To print the value of Energy, do just
WRITE(*,*) Energy

Related

How to call Fortran dll with function as argument in C

I use VS2013 and Intel Visual Fortran, then make a dll from Fortran code.
In Fortran subroutine, it has 3 arguments, "fa" for passing a function, "a" for passing an array, "b" for passing a number. But it doesn't work when I call it in VC++.
Update:
Well... program above is chaotic, so I remodify program below. I create a fortran dll that it can pass an array to sum its elements and call a c function.
module callctest
use, intrinsic :: iso_c_binding
implicit none
private
public callcfun
contains
subroutine callcfun(a,b) bind(C,name = "callcfun")
!DEC$ ATTRIBUTES DLLEXPORT :: callcfun
implicit none
real(c_double), dimension(*):: a !receive an array from c
type(c_funptr), value :: b ! receive a c function
real, parameter::pi=3.14159
integer :: i
real :: sum = 0.0
do i = 1,3 ! sum the array elements
sum = sum+a(i)
end do
write(*,*) 'total',sum
return
end subroutine callcfun
end module callctest
And c code that it call fortran subroutine:
#include "stdafx.h"
#include <iostream>
using namespace std;
extern "C" {
void callcfun( double[], void(f)(int)); //
}
void sayhello(int a){
cout << "Hi! fortran " <<a<< endl;
}
int main(){
double a[] = { 10.0, 50, 3.0 };
callcfun(a, sayhello(50));
system("pause");
return 0;
}
In c program, function "sayhello" print words "Hi! fortran" and an integer, I want to call sayhello functionby calling "callcfun( array, function )" which is written by fortran.
It works when I call "callcfun( array, function )" in c program if function
like "sayhello" only print "Hi! fortran". But I add an int argument for sayhello function so that it print words "Hi! fortran" and an integer argument. Function "callcfun" doesn't execute successfully.
Error list:
Error 1 error C2664: 'void callcfun(double [],void (__cdecl *)(int))' : cannot convert argument 2 from 'void' to 'void (__cdecl *)(int)' c:\users\emlab\documents\visual studio 2013\projects\vc++\call_for_ex\call_for_ex\call_for_ex.cpp 21 1 call_for_ex
2 IntelliSense: argument of type "void" is incompatible with parameter of
type "void (*)(int)" c:\Users\EMlab\Documents\Visual Studio
2013\Projects\VC++\call_for_ex\call_for_ex\call_for_ex.cpp 21 14 call_for_ex
Errors show the problem in the c function, how to pass the c function back to fortran dll then call it in fortran?
For a Fortran procedure to be interoperable, the BIND(C) attribute is required. Both Fortran procedures are missing this attribute.
For a procedure to be exported from a DLL on Windows, the symbolic name of the procedure must ultimately be supplied to the linker. (There are three ways of doing this: a source directive passed through by the compiler into the object code (as per the !DEC$ ATTRIBUTES DLLEXPORT directive used with the arraysum procedure), by listing the procedure name in a module definition file or by listing the name after /EXPORT on the linker command line - I am assuming that the two latter methods have not been used.) Given the source directive approach of nominating one procedure has been used for one of the procedures (arraysum) to be exported, that method should also be used for the other procedure (fcn) that needs to be exported.
For a C++ function to have C linkage, it must be declared with extern "C". There is no such declaration for fcn in the C++ code. (The absence of any declaration for fcn means that C++ code should not have compiled.)
The import library (.lib) generated by the linker when building the Fortran DLL must be provided to the linker when the exe is built from the C++ code. Typically this is done within Visual Studio by providing the import library as an "Additional Dependency" on the Linker > Input property page.

f2py Fortran function interfaces compiling error

f2py gives an error when I try compile FORTRAN subroutine, from which I call another FORTRAN function passing array to it.
I simplified code to leave the problem only.
SUBROUTINE MAS (matrix, a)
IMPLICIT NONE
INTERFACE
LOGICAL FUNCTION LTRY(input_array)
IMPLICIT NONE
INTEGER*4 :: input_array(:,:)
END FUNCTION LTRY
END INTERFACE
INTEGER*4 :: matrix (:,:)
!f2py INTENT(INOUT) :: matrix(:,:)
INTEGER*4 a
!f2py INTENT(INOUT) :: a
a = 1
IF ( LTRY (matrix)) a = 2
END SUBROUTINE
LOGICAL FUNCTION LTRY(input_array)
IMPLICIT NONE
INTEGER*4 :: input_array (:,:)
IF ( ANY(input_array == 0)) LTRY = .FALSE.
END FUNCTION LTRY
After I try to compile this using
f2py -c -m ptest ptest.f90
I get a tremendous number of errors. What's wrong?
Using Ubuntu and gfortran compiler.
Here is compiler output (part with error reports):
gfortran:f77: /tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:16.35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:18.72:
integer, dimension(:,:) :: input
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:19.72:
logical :: ltry
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:20.17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:40.32:
ltryf2pywrap = .not.(.not.ltry(input_array))
1
Error: Operand of .not. operator at (1) is INTEGER(4)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:16.35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:18.72:
integer, dimension(:,:) :: input
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:19.72:
logical :: ltry
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:20.17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:40.32:
ltryf2pywrap = .not.(.not.ltry(input_array))
1
Error: Operand of .not. operator at (1) is INTEGER(4)
error: Command "/usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops -I/tmp/tmpSZHMCR/src.linux-i686-2.7 -I/usr/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c -c /tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f -o /tmp/tmpSZHMCR/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.o" failed with exit status 1
Compilation failed.
Some errors look quite strange. For example compiler considers logical function as an integer.
Unfortunately, you have not indicated which type of error you get.
I have tried to compile it on my system, and I do get error messages:
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:16:35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:18:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:19:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:20:17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:16:35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:18:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:19:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:20:17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
Looking into the wrapped file, we see that the wrapper has made a very dubious decision: It has added comments at the end of the line, but then line-wrapped the comment without declaring it a comment in the second line:
C -*- fortran -*-
C This file is autogenerated with f2py (version:2)
C It contains Fortran 77 wrappers to fortran functions.
subroutine f2pywrapmas (matrix, a, f2py_matrix_d0, f2py_matr
&ix_d1)
integer*4 a
integer f2py_matrix_d0
integer f2py_matrix_d1
integer*4 matrix(f2py_matrix_d0,f2py_matrix_d1)
interface
subroutine mas(matrix,a)
integer*4, dimension(:,:) :: matrix
integer*4 :: a
interface ! in :ptest:ptest.f90:mas
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
&wn_interface
integer, dimension(:,:) :: input
logical :: ltry
end function ltry
end interface
end subroutine mas
end interface
call mas(matrix, a)
end
I don't know how to help you, though. But I do suggest you post your actual error messages in the question.

Fortran Call Errors

In my Fortran code, I have the commands:
CALL EXPECTATION(X, 0.5D0*SIGMAZ, Z_EXPECTATION)
WRITE(1,*) T, Z_EXPECTATION
CALL EXPECTATION(X, 0.5D0*SIGMAY, Y_EXPECTATION)
WRITE(4,*) T, Y_EXPECTATION
for which I get the errors:
Error: Symbol ‘sigmay’ at (1) has no IMPLICIT type
Error: Symbol ‘sigmaz’ at (1) has no IMPLICIT type
But I get no error for a similar command:
CALL EXPECTATION(X, 0.5D0*SIGMAX, X_EXPECTATION)
WRITE(3,*) T, X_EXPECTATION
What could be the issue? I am calling the variables from the same subroutine and I have defined them to be
COMPLEX*16, DIMENSION(2,2) :: SIGMAX, SIGMAY SIGMAZ
You forgot a comma in the declaration between SIGMAY and SIGMAZ. Since Fortran doesn't care about whitespaces, it created only two complex variables: SIGMAX and SIGMAYSIGMAZ.
Just add the comma and your code should compile fine.

error 2296: '^' : illegal , left operand has type 'double'

Part of my code:
double function (double x)
{
f = x^5-3*x^4+3*x^3-2*x^2-5;
return f;
}
Problem: I am getting following errors for this part of the code:
error C2296: '^' : illegal , left operand has type 'double'
error C2297: '^' : illegal , right operand has type 'double'
My Goal: I am writing a code to find the roots of the following polynomial in C++, Visual Studio 2012:
I am not sure how to solve this error since I am learning C++ and this is my first time I encountered this error. There are only two aforementioned errors; rest of my code is error-free. Your help will be much appreciated. Thank you!
The ^ operator in C/C++ is not an exponent operator (by default) - it's a bitwise XOR operator, and doesn't work on doubles.
Instead, use the pow function.

Converting from var to var&

How can I convert a variable of type var or var* to var&
I've to use a function which takes an object of var class(suppose there's a class). The example code was given like this:-
testFunc(false, namespace1::namespace2::var(), 100);
in function declaration it says that the second parameter is of type namespace1::namespace2::var&, I can create namespace1::namespace2::var or namespace1::namespace2::var*, but how do I create namespace1::namespace2::var&?
I know that's too basic question but I couldn't figure it out.
Edit:
I've tried using just var, but it gives some odd errors. I am pretty sure that's some kind of fault in the function I am using. Here're the errors:-
Error 3 error C2825: 'CType': must be a class or namespace when followed by '::'
Error 4 error C2039: 'TypeCode' : is not a member of '`global namespace''
Error 5 error C2146: syntax error : missing ',' before identifier 'TypeCode'
Error 6 error C2065: 'TypeCode' : undeclared identifier
Error 7 error C3203: 'CustomType' : unspecialized class template can't be used as a template argument for template parameter 'Base', expected a real type
Edit 2
I thought it'd be hard to answer if I include real code, since it's complicated. But have a look if it helps. The real function's signature is like this:-
virtual bool opRaiseEvent(bool reliable, const Common::Hashtable& parameters, nByte eventCode, nByte channelID=0, int* targetPlayers=NULL, short numTargetPlayers=NULL);
and the example code used the function like this:-
mLoadBalancingClient.opRaiseEvent(false, ExitGames::Common::Hashtable(), 100);
which was working fine. But now I want to add data to the HashTable, so I need to create an object of it and then pass it to the function. It's not accepting a pointer or normal variable. I don't know why it's working with just HashTable().
It means the second parameter is passed by reference. You have to simply pass:
namespace1::namespace2::var
This should work :
const Common::Hashtable param = namespace1::namespace2::var();
opRaiseEvent(false, param, 100);
namespace1::namespace2::var v;
testFunc(false, v, 100);