***********************************************************************
*
*     Derivative.f
*     A program created for Programming Workshop Spring 06
*     At Marlboro College taught by Jim Mahoney
*
*     Written by Jesse Welch
*     
*     This program will take input from the user, namely a function,
*     this function can then be differentiated numerically or the
*     functional derivative.  There are 6 trig and log functions built
*     in as well as the option for single term polynomial functions. 
*     The newest version of this program can also take a function as
*     input which is then set into a differential equation.  This 
*     equation takes the form Y'(x,y) = F(x,y), where F(x,y) is the
*     user inputted function.
*
*     All text input must be entered in lowercase letters
*
*     Variables:
*     inx : x value the function is to be evaluated at
*     const1: overall numerical constantin front of function 
*     const2: numerical argument of function
*     xinit: initial x value for diff. eq. 
*     yinit: initial y value for diff. eq. 
*     xnext: dummy variable used in loop for diff. eq.
*     deltx: increment of increase for diff. eq.
*     n: dummy index variable for loop.
*     niter: number of increments to go through in diff. eq.
*     a: power to which x is raised in F(x,y)
*     b: power to which y is raised in F(x,y)
*     func: user inputted function, to be differentiated
*     pick1: generic variable for menu access
*     variable: variable of function to be differentiated
*     func2:just aesthetic, to show what was input by user
*     
*     Version History:
*     1.0 - Output trig function values from user input
*     1.1 - Added in logarithmic functions
*     2.0 - Added in the derivative option
*     3.0 - Added in the option for derivative values and functions
*     4.0 - Added in the option for polynomial differentiation
*     5.0 (Final Release) - There is now the option for solutions
*           to differential equations using Euler's method.
***********************************************************************
      program  Derivative
      
      real inx,const1,const2,xinit, yinit, xnext, deltx
      integer n, niter, a, b, c
      character func, pick1, variable
      character*(3) func2
    

      write(*,*) 'Would you like to:'
      write(*,*) '(a) Take a derivative?'
      write(*,*) '(b) Solve a diff. equation with Eulers technique?'
      read*, pick1
*     write(*,*) pick1
      if (pick1 .eq. 'a') then
         write(*,*) 'Would you like to take the derivative of :'
         write(*,*) '(a) Trig or log function, (b) Polynomial'
         read*, pick1
         
         
         if (pick1 .eq. 'a') then
            write(*,*) 'Whats the function you would like to work with?'
            write(*,*) '(a) sin, (b) cos, (c) tan'
            write(*,*) '(d) log, (e) ln,  (f) exp'
            read*, func
*     write(*,*) func
            write(*,*) 'What quantities are involved in this function?'
            write(*,*) 'In form constant, function, argument, variable'
            read*, const1, func2, const2, variable
            write(*,*) 'You have chosen '
            write(*,*) const1,'*', func2,'(',const2, variable, ')'
            write(*,*) 'Want the derivative (f)unction or (v)alue?' 
            read*, pick1
*     write(*,*) pick1
**********************************************************************
*  This section performs a functional trig/log derivative
**********************************************************************
            if (pick1 .eq. 'f') then       
               if (func .eq. 'a') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the derivative of ', func2 , ' is...'
                  write(*,*) const1*const2,'*Cos(',const2,variable,')'
               else if (func .eq. 'b') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the derivative of ', func2 , ' is...'
                  write(*,*)-1*const1*const2,'*Sin(',const2,variable,')'
               else if (func .eq. 'c') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the derivative of ', func2 , ' is...'
                  write(*,*)const1*const2,'1/Cos^2(',const2,variable,')'
               else if (func .eq. 'd') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the derivative of ', func2 , ' is...'
                  write(*,*) const1,'*(1/ln(10))','* (1/(',variable,'))'
               else if (func .eq. 'e') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the derivative of ', func2 , ' is...'
                  write(*,*) const1, '*(1/(',variable,'))'
               else if (func .eq. 'f') then 
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the derivative of ', func2 , ' is...'
                  write(*,*) const1*const2,'(*exp(',const2,variable,'))'
               else
                  write(*,*) 'Inproper input'
               endif
               
            else if (pick1 .eq. 'v') then

**********************************************************************
*  This section performs a numerical derivative
**********************************************************************               
               write(*,*) 'What x value are you interested in?'
               read*, inx
*     write(*,*) inx
               if (func .eq. 'a') then
                  write(*,*) 'You have chosen ', func
                  write(*,*) 'And the value of the derivative of ',
     $                 func2,' at ', inx , ' is...'
                  write(*,*) const1*const2*Cos(1.0*const2*inx)
               else if (func .eq. 'b') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the value of the derivative of ',
     $                 func2,' at ', inx , ' is...'
                  write(*,*) -1.0*const1*const2*Sin(1.0*const2*inx)
               else if (func .eq. 'c') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the value of the derivative of ',
     $                 func2,' at ', inx , ' is...'
                  write(*,*)const1*const2*(1.0/(Cos(1.0*const2*inx)*2))
               else if (func .eq. 'd') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the value of the derivative of ',
     $                 func2,' at ', inx , ' is...'
                  write(*,*) const1*(1/(LOG(10.0)))*(1.0/(inx))
               else if (func .eq. 'e') then
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the value of the derivative of ',
     $                 func2, ' at ', inx , ' is...'
                  write(*,*) const1*(1.0/inx)
               else if (func .eq. 'f') then 
                  write(*,*) 'You have chosen ', func2
                  write(*,*) 'And the value of the derivative of ',
     $                 func,' at ', inx , ' is...'
                  write(*,*) const1*const2*Exp(1.0*const2*itx)
               else   
                  write(*,*) 'Inproper input'           
               endif
            end if

**********************************************************************
*  This section performs a functional polynomial derivative
**********************************************************************            
         else
            write(*,*) 'What polynomial you would like differentiated?'
            write(*,*) 'In the form constant variable power'
            read*, const1, variable, const2
*     write(*,*) const1, variable, const2
            write(*,*) 'How many times would you like to differentiate?'
            read*, c
*     write(*,*) c
            do 10 n = 1, c
               if (const2 .gt. 0) then
                  const1 = const1*const2
                  const2 = const2 - 1
                  write(*,*) 'After',n,' derivatives, your function is',
     $                ' now ', const1,'*', variable,'^',const2
               else
                  write(*,*) 'After',n,' derivatives, your function is',
     $                 ' now equal to zero.'
               endif
 10         continue
         end if

**********************************************************************
*  This section performs Euler's method of numerical differential 
*  solutions   
**********************************************************************

      else
         write(*,*) 'What is the function you wish to solve?'
         write(*,*) 'In the form of constant, x power, y power'
         read*, const1,a,b
*     write(*,*) const1, a, b
         write(*,*) 'What are the initial x and y values, ie y[?]=?'
         write(*,*) 'In the form of xvalue yvalue'
         read*, xinit, yinit
*     write(*,*) xinit, yinit
         write(*,*) 'What length increment do you want to use?'
         read*, deltx
*     write(*,*) deltx
         write(*,*) 'What is the number of iterations you wish',
     $        'to calculate?'
         read*, niter
*     write(*,*) niter
         do 20 n = 1, niter
            xnext = xinit + deltx
            yinit = yinit + (const1*((xinit)**a)* ((yinit)**b)) * deltx
            xinit = xnext
            write(*,*) 'X(',n,') =', xinit
            write(*,*) 'Y(',n,') =', yinit
 20      continue
      end if
      end
      

