program calc
	use cubeClass
	implicit none
	character(len=200)::input1,input2,output
	character(len=1)::op
	type(cube)::cube1, cube2, result_cube

	logical::exists,input2IsNumber=.false.
	integer::io
	real(kind=8)::value

	call getarg(1,input1)
	call getarg(2,op)
	call getarg(3,input2)
	call getarg(4,output)

	cube1 = readCube(input1)

	INQUIRE(FILE=input2, EXIST=exists)
	if(.not. exists) then
		if (trim(input2) == "")then
			write(*,*) 'No secend input file was specified!'
			stop
		end if
		read ( input2, '(F50.0)', iostat=io ) value
		if ( io /= 0 ) THEN
			write(*,*) 'The input file "', trim(input2), '" does not exist and is not a number!'
			stop
		end if
		input2IsNumber=.true.
	else
		cube2 = readCube(input2)

		if (cube1%nx.NE.cube2%nx.OR.cube1%ny.NE.cube2%ny.OR.cube1%nz.NE.cube2%nz.OR. &
		cube1%origin_x.NE.cube2%origin_x.OR.cube1%origin_y.NE.cube2%origin_y.OR.cube1%origin_z.NE.cube2%origin_z.OR. &
		all(cube1%axis_x.NE.cube2%axis_x).OR.all(cube1%axis_y.NE.cube2%axis_y).OR.all(cube1%axis_z.NE.cube2%axis_z)) then
			write(*,*) 'The grids of the input files "',trim(input1),'" and "',trim(input2),'" is not equal!'
			stop
		end if
	end if

	!result_cube gets header, grid and atoms of cube1
	result_cube=cube1

	  select case( op )
		case( "+" )
			if (input2IsNumber) then
				result_cube%values = cube1%values + value
			else
				result_cube%values = cube1%values + cube2%values
			end if
		case( "-" )
			if (input2IsNumber) then
				result_cube%values = cube1%values - value
			else
				result_cube%values = cube1%values - cube2%values
			end if
		case( "*" )
			if (input2IsNumber) then
				result_cube%values = cube1%values * value
			else
				result_cube%values = cube1%values * cube2%values
			end if
		case( "/" )
			if (input2IsNumber) then
				result_cube%values = cube1%values / value
			else
				result_cube%values = cube1%values / cube2%values
			end if
		case default
			write(*,*) 'The specified operator "', op ,'" was not recognized!'
			stop
		end select

	result_cube%header1 = "Result of "//trim(input1)//" "//op//" "//trim(input2)
	call writeCube(result_cube,output)

end program calc


      SUBROUTINE DSUBN(X,NMAX,XMAX,D)
C-------------------------------------------------------------------
C Translation of Gautschi'f CACM Algorithm 282 for
C   derivatives of Ei(x).
C
C  Intrinsic functions required are:
C
C      ABS, EXP, INT, LOG, MIN
C
C-------------------------------------------------------------------
      LOGICAL BOOL1, BOOL2
      INTEGER J,NMAX,N0,MINI,N,N1,LIM
CS    REAL
      DOUBLE PRECISION
     1     B0,B1,B2,B3,B4,B5,B6,C0,C1,D,E,EN,ONE,P,Q,T,TEN,
     2     TWO,X,XMAX,X1,Z,ZERO
      DIMENSION D(0:NMAX)
CS    DATA ZERO/0.0E0/,ONE/1.0E0/,TWO/2.0E0/,TEN/10.0E0/
CS    DATA C0/2.7183E0/,C1/4.67452E1/
CS    DATA B0/5.7941E-5/,B1/-1.76148E-3/,B2/2.08645E-2/,
CS   1     B3/-1.29013E-1/,B4/8.5777E-1/,B5/1.0125E0/,B6/7.75E-1/
      DATA ZERO/0.0D0/,ONE/1.0D0/,TWO/2.0D0/,TEN/10.0D0/
      DATA C0/2.7183D0/,C1/4.67452D1/
      DATA B0/5.7941D-5/,B1/-1.76148D-3/,B2/2.08645D-2/,
     1     B3/-1.29013D-1/,B4/8.5777D-1/,B5/1.0125D0/,B6/7.75D-1/
C-------------------------------------------------------------------
      X1 = ABS(X)
      N0 = INT(X1)
      E = EXP(X)
      D(0) = E/X
      BOOL1 = (X .LT. ZERO) .OR. (X1 .LE. TWO)
      BOOL2 = N0 .LT. NMAX
      MINI = MIN(N0,NMAX)
      IF (BOOL1) THEN
            LIM = NMAX
         ELSE
            LIM = MINI
      END IF
      N = 1
      EN = ONE
   50 D(N) = (E - EN*D(N-1))/X
         N = N +1
         EN = EN + ONE
         IF (X1 .LT. ONE) THEN
               IF ((ABS(D(N-1)) .LT. ABS(XMAX*X/EN)) .AND.
     1            (N .LE. LIM)) GO TO 50
            ELSE
               IF ((ABS(D(N-1)/X) .LT. XMAX/EN) .AND. (N .LE. LIM))
     1            GO TO 50
         END IF
         DO 100 J = N, LIM
            D(N) = ZERO
  100    CONTINUE
      IF ((.NOT. BOOL1) .AND. BOOL2) THEN
         T = (X1+C1)/(C0*X1)
         IF (T .LT. TEN) THEN
               T = ((((B0*T + B1)*T + B2)*T + B3)*T + B4)*T + B5
            ELSE
               Z = LOG(T) - B6
               P = (B6-LOG(Z))/(ONE+Z)
               P = ONE/(ONE+P)
               T = T*P/Z
         END IF
         N1 = C0*X1*T - ONE
         IF (N1 .LT. NMAX) N1 = NMAX
         Q = ONE/X
         EN = ONE
         DO 120 N = 1,N1+1
            Q = -EN*Q/X
            EN = EN+ONE
  120    CONTINUE
         DO 140 N = N1,N0+1,-1
            EN = EN - ONE
            Q = (E-X*Q)/EN
            IF (N .LE. NMAX) D(N) = Q
  140    CONTINUE
      END IF
      RETURN
C---------- Last line of DSUBN ----------
      END


      SUBROUTINE COMMAX(Z,N,T,AM,M)
      DIMENSION T(1),AM(1)
      COMPLEX Z(1)
      DO 100 I=1,M
      T(I)=0.0
  100 AM(I) = 0.0
      N2 = N - 2
      DO 700 I=1,N2
      Y1 = REAL(Z(I))
      Y2 = REAL(Z(I+1))
      Y3 = REAL(Z(I+2))
      A=(Y1+Y3)/2.0-Y2
      IF (A.GE.0.0) GO TO 600
      B = Y2-Y1-A
      C = Y1
      Y0 = -(B*B-4.0*A*C)/4.0/A
      IF (Y0.LE.0.0) GO TO 600
      X0 = -B/2.0/A
      IF (X0.LT.0.0) GO TO 600
      IF (X0.GT.2.0) GO TO 600
      TP=X0+FLOAT(I)-1.0
      DO 200 J=1,M
      IF(ABS(TP-T(J)) .LT. 1.0) GO TO 700
      IF(Y0 .GT.AM(J)) GO TO 300
  200 CONTINUE
      GO TO 600
  300 J1=J+1
      IF (J1.GT.M) GO TO 500
      DO 400 K=J1,M
      L = M+J1-K
      AM(L) = AM(L-1)
  400 T(L) = T(L-1)
  500 AM(J) = Y0
      T(J)=TP
  600 CONTINUE
  700 CONTINUE
      RETURN
      END