c_______________________________________________________________________________
c
c     PROGRAMA PRINCIPAL (Version DIMENSIONAMIENTO DINAMICO + MEMORY ALLOCATION)
c
c     Este programa calcula el producto matricial
c
c               C             = A             . B
c               ~ (nfc x ncc)   ~ (nfa x nca)   ~ (nfb x ncb)
c
c     siendo nca = nfb, nfc = nfa, ncc = ncb.
c
c     Las matrices A y B se encuentran almacenadas en sendos archivos de texto.
c     La matriz producto C se escribe en un archivo de texto del mismo tipo.
c
c     Notas:
c            Se utiliza DIMENSIONAMIENTO DINAMICO para almacenar las matrices.
c            La memoria para dim. dinamico se reserva al ejecutar el programa.
c            No es preciso recompilarlo para aumentar/disminuir la memoria disp.
c_______________________________________________________________________________

      implicit real*8 (a-h,o-z)




      allocatable work(:)                                           ! Fortran 90

      character matrA*80, matrB*80, matrC*80
      character fmt*80

C.....Preparacion de memoria para dim. dinamico
      write(6,'(/a,$)') ' No. maximo de componentes      -> nkp = '
      read(5,*) nkp
      allocate(work(nkp),STAT=ist)                          ! RESERVA DE MEMORIA
      if (ist.ne.0) call ErrorFatal('Memoria insuficiente', 4)
      kplibre=1


c.....Leemos la matriz A
    1 write(6,'(/a,$)') ' Archivo correspondiente a la matriz A : '
      read(5,'(a)') matrA
      logA=11
      open(unit=logA,status='old',file=matrA,err=1)  ! abrimos el archivo
      read(logA,'()')                                ! ignoramos primera linea
      read(logA,'(a)') fmt                           ! formato de lectura
      read(logA,fmt) nfa,nca                         ! dimensiones de matriz A
      call DimDinamico(nkp,kplibre,nfa*nca,kpa)      ! espacio de memoria para A

      call LeerMatriz(logA,fmt,nfa,nca,work(kpa))    ! leemos la matriz A
      close(unit=logA,status='keep')                 ! cerramos el archivo


c.....Leemos la matriz B
    2 write(6,'(/a,$)') ' Archivo correspondiente a la matriz B : '
      read(5,'(a)') matrB
      logB=12
      open(unit=logB,status='old',file=matrB,err=2)  ! abrimos el archivo
      read(logB,'()')                                ! ignoramos primera linea
      read(logB,'(a)') fmt                           ! formato de lectura
      read(logB,fmt) nfb,ncb                         ! dimensiones de matriz B
      call DimDinamico(nkp,kplibre,nfb*ncb,kpb)      ! espacio de memoria para B

      call LeerMatriz(logB,fmt,nfb,ncb,work(kpb))    ! leemos la matriz B
      close(unit=logB,status='keep')                 ! cerramos el archivo


c.....Calculamos y escribimos la matriz producto C = A * B
    3 write(6,'(/a,$)') ' Archivo correspondiente a la matriz C : '
      read(5,'(a)') matrC
      logC=13
      open(unit=logC,status='new',file=matrC,err=3)  ! abrimos el archivo
      write(logC,'(a)') 'Matriz Producto C = A . B'  ! titulo en primera linea
      fmt='(2i6,d25.16)'
      write(logC,'(a)') fmt                          ! formato de escritura
      nfc=nfa
      ncc=ncb
      write(logC,fmt) nfc,ncc                        ! dimensiones de matriz C
      call DimDinamico(nkp,kplibre,nfc*ncc,kpc)      ! espacio de memoria para C

      call MultiplicarMatrices(nfa,nca,work(kpa),
     .                         nfb,ncb,work(kpb),
     .                         nfc,ncc,work(kpc))    ! calculamos C = A . B
      call EscribirMatriz(LogC,fmt,nfc,ncc,work(kpc))! escribimos la matriz C
      close(unit=logC,status='keep')                 ! cerramos el archivo 


c.....Fin de programa
      call exit(0)

      end


c____________________________________________________________________DimDinamico

      Subroutine DimDinamico(nkp,kplibre,ncomponentes,kp)

      kp=kplibre
      kplibre=kplibre+ncomponentes
      if (kplibre.gt.nkp+1) call ErrorFatal('Memoria insuficiente', 4)

      return
      end
