!Polyize.f95
!2021.04.06.1640cdt JMS- Traveler2/Athlon64/WinXPPro/APF9.0/Ogl1.2.1
                                                  !.1630 fixed bug in line #337
!Table of Contents:
!Module PolyDef
! Program Main
!  Subroutine ImportBinFile(iP)
!  Subroutine BinFileCsvReport(iP)
!  Subroutine MatrixCsvWriter
!  Subroutine ValuesSequence(iP)
!  Subroutine ExampleIputs(iP)
!  Subroutine DataInToCoesOut(iP)
!  Subroutine CoesInToDataOut(iP)
!  Subroutine CoefficientCount(iP)
!  Subroutine DisclaimerEtc(iP)
!---------------------------------------------------------------------------7 9
Module PolyizeDef
!use PolyDef                                                 !JMS 2021.03.27
  integer*4            ::nNameChars!# of characters in the filename.
  character            ::cBinFilein*79!Filename of the binary input data

 type ::  PolyizeRec
  integer*4            ::nVT       !Variables- total number [1,2,...,10]
  integer*4            ::nOrdMax   !Largest of the nOrd()'s
  integer*4            ::nCT       !Coefficients total number
  integer*4            ::nOrd(10)  !Even-orders of polynomial of each variable
  integer*4            ::iPolyClass!Coefficients type:
  integer*4            ::iCoeDigits!Number of digits for exact values
  integer*4            ::iCoeDeciPl!Number of decimal places
  real*16              :: CoeDiv   !Divisor of Coe()- real
  real*16              :: CoeMaxScaled!MaxAbs coefficient in .bin-
  integer*4            ::iPowDigits!Number of digits for exact values
  integer*4            ::iPowDeciPl!Number of decimal places
  real*16              :: PowDiv   !Divisor of Coe()- real
  real*16              :: PowMaxScaled!MaxAbs coefficient in .bin-
 end type PolyizeRec
 type(PolyizeRec)::Pr !This is the .bin file's front-end binary information.

! --nVT and nOrd(1:nVT) determine nCT and the size of these arrays:
  real*16  ,allocatable::X( :,:)    !Coefficient values in [-1,1]
!                  (0:nOrdMax,nVT)
  integer*4,allocatable::nVnC(:,:)  !Indexes & powers lookup table
!                          (nVT,nCT)
  real*16  ,allocatable:: Coe(:,:)  !The matrix to be inverted
!                          (nCT,nCT)
  real*16  ,allocatable:: Pow(:,:)  !The matrix to be inverted
!                          (nCT,nCT)
  real*16  ,allocatable:: DataSeq(:)!The user's data vector
!                               (nCT)
  real*16  ,allocatable:: CoeSeq(:) !The user's data vector
!                              (nCT)

! --The following often-used variables are copied out of the Pr record:
  integer*4            ::nVT       !Variables- total number [1,2,...,10]
  integer*4            ::nOrdMax   !Largest of the nOrd()'s
  integer*4            ::nCT       !Coefficients total number
  integer*4            ::nOrd(10)  !Even-orders of polynomial of each variable
  real*16              :: CoeDiv   !Divisor of Coe()- real
  real*16              :: PowDiv   !Divisor of Coe()- real
  integer*4            ::iDecPlaces=12
  integer*4            ::iDomain=1
  character*1    ::AugHex(0:20)=(/"0","1","2","3","4","5","6","7","8","9","a" &
                                     ,"b","c","d","e","f","g","h","i","j","k"/)
!---------------------------------------
! --Runtime environment variables:
  character::cIniFIle*79  ='Polyize.ini'c
  character::cOutFile*79  ='Polyize.txt'c
! --Unit#'s for input/output:
  integer*4::uD  =14 !: Open(uD...) for reading & writing documentation
  integer*4::uP  =13 !: write(uP,...) Print to- file
  integer*4::uS  = 6 !: write(uS,...) Print to- screen
  integer*4::uT  = 0 ! [0,uP, or uS] temporarily requested outputs
!                     if(uT>5) write(uT,...)
! --Memory allocation variables:
  logical  ::LExists
  integer*4::iAlloc       !Allocation flag: used with allocatable arrays
  integer*4::iPolyAlloc =0!:unAllocated; =1:Allocated
! --Timeing variables:
  real*16              ::TimeEstMin
  character            ::Chrono(0:9)*22!TimeStamps:
!                                     (0):                for differential use
!                                     (1):                Start
!                                     (2):Data entry    - done
!Contains
End Module PolyizeDef
!---------------------------------------------------------------------------7 9

!---------------------------------------------------------------------------7 9
Program Main                                                   !2021.04.06.1640
!2021.04.06.1640cdt JMS- Opens an output file & calls PolyGen()
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
 !--Internals
  integer*4::WhatNext != 0:end
!                      = 1:provide a data template
!                      = 2:compute poly coefficients
  character::cL*80
  !--EndDefs---------------------------
   uP = 13  ! = 6 ...for screen only (e.g. for no writes to a hard drive.)
                                                  call DateAndTime22(Chrono(1))
   !--- Open output
   if(uP.gt.12) then
     open( uP,file=cOutFile,action='write',err=10)
       cL='Opening output file: '//cOutFile    ;call TimeStamp(cL,chrono(1),uP)
       goto 20
   endif !uP>12
10     uP=6
       cL='The computer monitor will be the output. 'c ;call WSF(cL,uP)
       cL=''c                                                 ;call WSF(cL,uP)
20 continue
   cL=''c                                                      ;call WSF(cL,uP)
   cL='This is:    "Polyize.exe",         By: Jeff Setterholm'c
                                                               ;call WSF(cL,uP)
   cL='        Version 1.1 2021.04.06    Lakeville, MN 55044 USA'c
                                                                call WSF(cL,uP)
   cL=''c                                                      ;call WSF(cL,uP)

   call DisclaimerEtc(uP) !//////////////////////

   call ImportBinFile(uP) !//////////////////////

   cL=''c                                                      ;call WSF(cL,uP)
                                                  call DateAndTime22(Chrono(2))
   write(cL,"('.bin file content - loaded, parsed, &  ready.')")
                                                call TimeStamp(cL,Chrono(2),uP)
!  call ElapsedTime(Chrono(1),Chrono(2),Chrono(9),TimeEstMin,0)
!  call TimeStamp( & !                                  |
!  "                                       task`s time: "c       ,Chrono(9),uP)

50 continue
   cL=''c                                                      ;call WSF(cL,uP)
   write( 6,"(' What next?   -3 : Write the `CoefficientCount` table.')")
   write( 6,"(12x,'  -2 : *.bin -> *.csv `Comma Separated Values` file.')")
   write( 6,& 
  "(12x,'  -1 : Write `ValuesSequenceInfo.txt`,`DataIn.txt`,&`PolysIn.txt.`')")
   write( 6,"(12x,'   0 : Quit.')")
   write( 6,"(12x,'  +1 : Process your `DataIn.txt`->`CoesOut.txt`.')")
   write( 6,"(12x,'  +2 : Process your `CoesIn.txt`->`DataOut.txt`.')")
   write( 6,"('Your choice = '\)")
   read(5,*) WhatNext
   write(uP,"('WhatNext=',i2)") WhatNext                       ;call WSF(cL,uP)
                                                  call DateAndTime22(Chrono(3))
   select case(WhatNext)
     case(-3) ! = -3 : Write the 'Coefficient Count Table'.
      call CoefficientCount(uP)

     case(-2) !=-2 : *.bin -> *.csv `Comma Separated Values` file.
      call BinFileCsvReport(uP) !////////////////
                                                  call DateAndTime22(Chrono(4))
      call ElapsedTime(Chrono(3),Chrono(4),Chrono(9),TimeEstMin,0)
      call TimeStamp( & !                                  |
      "                                       task`s time: "c    ,Chrono(9),uP)

     case(-1) != -1 :`ValuesSequenceInfo.txt`,'DataIn.txt,&'CoesIn.txt.
      call ValuesSequence(uP) !//////////////////
      call ExampleIputs(uP)   !//////////////////

     case( 1) ! = +1 : Process your `DataIn.txt`->`CoesOut.txt`.
      call DataInToCoesOut(uP)  !////////////////

     case( 2) ! = +2 : Process your `CoesIn.txt`->`DataOut.txt`.
      call CoesInToDataOut(uP)  !////////////////

     case default !Quit 
      goto 100

    end select!(WhatNext)
    goto 50

100 continue
   if(iPolyAlloc>0) then
     deallocate(X)
     deallocate(nVnC)
     deallocate(Pow)
     deallocate(Coe)
     deallocate(DataSeq)
     deallocate(CoeSeq)
     iPolyAlloc = 0
     if(uP>5) write(uP,"(1x,'Arrays deallocated')")
   endif!iPolyAlloc>0

   if(uP.gt.12) close(uP)
!  pause 'Press enter to continue - thus closing this output screen & exiting.'
End Program Main
!---------------------------------------------------------------------------7 9

Subroutine ImportBinFile(iP)
!2021.03.30.1545cdt JMS- Import the polynomial matrices to use.
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
  integer*4::iP           !Write enable>5: write(iP,...)
!--Internals
  integer*4::i,iFileBytes,nB
  character::cL*80
  !--EndDefs---------------------------
   open(unit=14,file=cIniFIle,action='read')
     read(14,*) cBinFileIn
   close(14)

   nNameChars=len_trim(cBinFileIn)
   write(Cl,"('Reading: ',79(a1,:))")(cBinFileIn(i:i),i=1,nNameChars)
                                                                call WSF(cL,uP)

   open(unit=14,file=cBinFileIn,form='binary',action='read')
     read(14)  Pr                        ! ...a known read

     nVT     = Pr.nVT
     nOrdMax = Pr.nOrdMax
     nCT     = Pr.nCT
     nOrd    = Pr.nOrd
     CoeDiv  = Pr.CoeDiv
     PowDiv  = Pr.PowDiv

!    --Allocate the arrays:
     allocate(X(0:nOrdMax,nVT),stat=iAlloc);       if(iAlloc /= 0) then
       pause 'X(0:nOrdMax,nVT) alloc. error. `Enter` to exit.'     ;stop; endif
     X        = 0._16                                ;iPolyAlloc = iPolyAlloc+1
     allocate(nVnC(nVT,nCT),stat=iAlloc);          if(iAlloc /= 0) then
       pause 'nVnC(nVT,nCT) alloc. error. `Enter` to exit.'        ;stop; endif
     nVnC      = 0                                   ;iPolyAlloc = iPolyAlloc+1
     allocate(Pow(nCT,nCT),stat=iAlloc);           if(iAlloc /= 0) then
         pause 'Pow(nCT,nCT) alloc. error. `Enter` to exit.'       ;stop; endif
     Pow       = 1._16                               ;iPolyAlloc = iPolyAlloc+1
     allocate(Coe(nCT,nCT),stat=iAlloc);           if(iAlloc /= 0) then
         pause 'Coe(nCT,nCT) alloc. error. `Enter` to exit.'       ;stop; endif
     Coe      = 1._16                                ;iPolyAlloc = iPolyAlloc+1
!    --Arrays needed to finish the .bin file read have been allocated.
!    --Now allocate the Data Sequence & Coefficient Sequence vectors:
     allocate(DataSeq(nCT),stat=iAlloc);           if(iAlloc /= 0) then
         pause 'DataSeq(nCT) alloc. error. `Enter` to exit.'       ;stop; endif
     DataSeq  = 1._16                                ;iPolyAlloc = iPolyAlloc+1
     allocate(CoeSeq(nCT),stat=iAlloc);            if(iAlloc /= 0) then
         pause 'CoeSeq(nCT,nCT) alloc. error. `Enter` to exit.'    ;stop; endif
     CoeSeq   = 1._16                                ;iPolyAlloc = iPolyAlloc+1

   write(  cL,  &
   "('Binary file data write/read sequence- integer*4`s & real*16`s:')")
                                                                call WSF(cL,uP)
   nB = sizeof(nVT);     iFileBytes =            nB               ;write(cL, &
   "(i12,', i* 4 nVT      -# of independent variables<=10    fixed size')") nB
                                                                call WSF(cL,uP)
   nB = sizeof(nOrdMax); iFileBytes = iFileBytes+nB               ;write(cL, &
   "(i12,', i* 4 nOrdMax  -Highest order variable    <=20     `    `'    )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(nCT);     iFileBytes = iFileBytes+nB               ;write(cL, &
   "(i12,', i* 4 nCT      -Number of polynomial coefficients   `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(nOrd);     iFileBytes = iFileBytes+nB              ;write(cL, &
   "(i12,', i* 4 nOrd(10) -Order of each variable  (1:nVT)     `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.iPolyClass);iFileBytes = iFileBytes+nB          ;write(cL, &
   "(i12,', i* 4 iPolyClass-=1:exact, =2:unscaled              `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.iCoeDigits);iFileBytes = iFileBytes+nB          ;write(cL, &
   "(i12,', i* 4 iCoeDigits- +***.  <-count                    `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.iCoeDeciPl);iFileBytes = iFileBytes+nB          ;write(cL, &
   "(i12,', i* 4 iCoeDeciPl-number of digits after .           `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.CoeDiv);   iFileBytes = iFileBytes+nB           ;write(cL, &
   "(i12,', r*16 CoeDiv   -Coe[,] matrix dividing factor       `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.CoeMaxScaled);   iFileBytes = iFileBytes+nB     ;write(cL, &
   "(i12,', r*16 CoeMaxScaled -AbsMax Coe[,] in .bin           `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.iPowDigits);iFileBytes = iFileBytes+nB          ;write(cL, &
   "(i12,', i* 4 iPowDigits- +***.  <-count                    `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.iPowDeciPl);iFileBytes = iFileBytes+nB          ;write(cL, &
   "(i12,', i* 4 iPowDeciPl-number of digits after .           `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.PowDiv);   iFileBytes = iFileBytes+nB           ;write(cL, &
   "(i12,', r*16 PowDiv   -Pow[,] matrix dividing factor       `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pr.PowMaxScaled);   iFileBytes = iFileBytes+nB     ;write(cL, &
   "(i12,', r*16 PowMaxScaled   -AbsMax Pow[,] in .bin         `    `'   )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(X);        iFileBytes = iFileBytes+nB              ;write(cL, &
   "(i12,', r*16 X[0:nOrdMax,nVT] -Variable values to use    allocated'  )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(nVnC);     iFileBytes = iFileBytes+nB              ;write(cL, &
   "(i12,', i* 4 nVnC[nVT   ,nCT] -Values combinations sequence  `'      )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Coe);      iFileBytes = iFileBytes+nB              ;write(cL, &
   "(i12,', r*16 Coe[ nCT   ,nCT] -The coefficients solver       `'      )") nB
                                                                call WSF(cL,uP)
   nB = sizeof(Pow);      iFileBytes = iFileBytes+nB              ;write(cL, &
   "(i12,', r*16 Pow[ nCT   ,nCT]      Coe[,] = inverse(Pow[,])  `'      )") nB
                                                                call WSF(cL,uP)
   write(  cL,"(i12,', Total Bytes')") iFileBytes;  call WSF(cL,uP)
   cL=''c                                                      ;call WSF(cL,uP)

   write(cL,"('All arrays needed have been successfully allocated')")
                                                                call WSF(cL,uP)
!    Cseq() = Coe[,] * Dseq()
!    Dseq() = Pow[,] * Cseq()
!    Dseq & Cseq are populated using nVnC[,] referencing the X[,] domain values

!    Complete the read of the .bin file...
     read(14)   X, nVnC, Coe, Pow
   close(14)
                                                                         return
End Subroutine ImportBinFile
!---------------------------------------------------------------------------7 9

Subroutine BinFileCsvReport(iP)
!2021.04.06.1630cdt JMS- Polyize's Comma Separated Value Summary. (Bug L#337)
 use PolyizeDef                                                  !  Fixed
!--End Globals
 implicit none
 !--Arguments
  integer*4::iP           !Write enable>5: write(iP,...)
 !--Internals
  integer*4::i,nV,N,nCol
  character::cL*80
 !--EndDefs---------------------------
     write(cL,"('')")                                  ;call WSF(cL,iP)
     write(cL,"('PolyizeCsvReport():')")
                                                        call WSF(cL,iP)
   cL=char(0); cL(           1:nNameChars-3) = cBinFilein(1:nNameChars-3)
               cL(nNameChars-2:nNameChars  ) ="csv"c
   !Use a spreadsheet to export perfect inverses as .csv's:
   open(unit=uD,file=cL,action='write')
   write(uD,"('Generated by : Polyize.exe|BinFileCsvReport'\)")
   write(uD,"('      runtime ',a22)") Chrono(3)
   write(uD, &
          "('Label indices are augmented hexadecimals: { 0,15}->{0:f}')")
   write(uD,"(19x,'-&-  16->g 17->h 18->i 19->j     20 ->   k')")
   write(uD,"(/'`Polyize.ini` has the name of the .bin file to read...'/)")
   write(uD,"('Reading: ',79(a1,:))")(cBinFileIn(i:i),i=1,len_trim(cBinFileIn))
   write(uD,"( i6.1,',:nVT        = # of Variables Total [1:7]')") nVT
   write(uD,"( i6.1,',:nOrdMax    = highest order variable'   )") nOrdMax
   write(uD,"( i6.1,',:nCT        = # of Coefficients Total'  )") nCT!x nOrdMax
   do nV=nVT,1,-1; write(uD,"(i6.1,\)") nOrd(nV); enddo!nV
   write(uD,"(',:nOrd - Order of each variable  <- sequence 7654321')")
   write(uD,"( i6.1,',:iPolyClass = 1:exact, =2:unscaled'    )") Pr.iPolyClass
   write(uD,"( i6.1,',:iCoeDigits = `+***.` <-count '        )") Pr.iCoeDigits
   write(uD,"( i6.1,',:iCoeDeciPl =number of digits after .' )") Pr.iCoeDeciPl
   write(uD,"(f30.9,',:CoeDiv = Coe[,] matrix dividing factor')")Pr.CoeDiv
   write(uD,"(f30.9,',:CoeMaxScaled = AbsMax Coe[,] in .bin' )")Pr.CoeMaxScaled
   write(uD,"( i6.1,',:iPowDigits = `+***.` <-count '        )") Pr.iPowDigits
   write(uD,"( i6.1,',:iPowDeciPl =number of digits after .' )") Pr.iPowDeciPl
   write(uD,"(f30.9,',:PowDiv = Coe[,] matrix dividing factor')")Pr.PowDiv
   write(uD,"(f30.9,',:PowMaxScaled = AbsMax Coe[,] in .bin' )")Pr.PowMaxScaled

   write(uD,"('The domain(s) of the sample points is/are:')")
                     write(uD,"('       N,' \)")
   do nV = nVT,1,-1; write(uD,"('  X(',i2,'),'\)") nV               ;enddo!nV
                     write(uD,"(' X(0:nOrd(nV),nVT)')")
   do N = 0,nOrdMax
         write(uD,"(i8,',',4x,\)") N
     do nV = nVT,1,-1
       if(N>nOrd(nV)) then
         write(uD,"('       ,'\)")
        else
         write(uD,"(f7.3,','\)") X(N,nV)
       endif!N>nOrd(nV)
     enddo!nd
         write(uD,"('')")
   enddo!N
     if(iDomain==1) &
     write(uD,"(/'Each domain is [-1. to +1.]')")
     if(iDomain==2) &
     write(uD,"(/'Each domain is [-N/2. to +N/2.]')")

     write(uD, &
       "(/'To exercise your model in the sequence needed by the Coe matrix,')")
     write(uD, &
  "('  -or- to synthesize an accurate dataset from polynomial coefficients,')")
     write(uD, &
 "('  use NvnC() below to select X() combinations above, or specific A()`s.')")
     write(uD,"('Sample # sequencer: nVnC(1:nVT,1:nCT)'\)")
     write(uD,"('   X(1) varies the most rapidly.')")
     do nCol = 1,nCT; write(uD,"(i8,','\)") nCol
       do nV = nVT,1,-1; write(uD,"( i7,','\)") nVnC(nV,nCol)       ;enddo!nV
                      write(uD,"(''      )")                        ;enddo!nCol

!write(uD,"(/ e12.3,', :[Coe*Pow-I] r*16 128-bit AbsMax inversion error'  )") &
!               CoePowMax

!---------------------------
     write(uD,"(/f25.3,', :Coefficients- AbsMax value (below)' )") &
                                                                Pr.CoeMaxScaled
     write(6,"('Coe[nCT,nCT] write progress bar...')")
     call MatrixCsvWriter( nCT,Coe,CoeDiv,'A','X' &
                          ,Pr.iCoeDigits,Pr.iCoeDeciPl,iP)
!---------------------------
     write(uD,"(/f25.3,', :Powers      - AbsMax value (below)' )") &
                                                                Pr.PowMaxScaled
     write(6,"('Pow[nCT,nCT] write progress bar...')")
     call MatrixCsvWriter( nCT,Pow,PowDiv,'X','A' &
                          ,Pr.iPowDigits,Pr.iPowDeciPl,iP)
!---------------------------
     call DisclaimerEtc(uD)

   close(uD)                                                            ;return
 End Subroutine BinFileCsvReport
!---------------------------------------------------------------------------7 9

Subroutine MatrixCsvWriter( nTot,A,ADiv,c1rows,c1cols,iADigits,iADeciPl,iP)
!2021.04.01.0850cdt JMS- Writes matrices Pow() & Coe() for export
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
  integer*4::nTot
  real*16  ::A(nTot,nTot) !Pow(,) or Coe(,)
  real*16  ::ADiv
  character::c1Rows*1     !"a" or "x"
  character::c1cols*1     !"a" or "x"
  integer*4::iADigits     !Number of digits for exact values
  integer*4::iADeciPl     !Number of decimal places
  integer*4::iP           !Write enable>5: write(iP,...)
!--Internals
  character*16::Format1
  character*13::Format2
  integer*4::nRow,nCol,nV,j
  integer*4::OutLength
  character::PrintString*40
  !--EndDefs---------------------------
   if(Pr.iPolyClass==1) &
   write(uD,"(f25.3,', :Matrix entry Exact integer divisor')") ADiv
   if(Pr.iPolyClass==2) &
   write(uD,"(f25.3,', :divisor       ...Unscaled ...non-exact')") ADiv

!  --For writing the matrix coefficient:
         Format1=char(0)
   if(iADeciPl<10) then
     write(Format1,"(a1,'sp',a1,' f',i2.2,a1,i1.1,a1,3a1,2a1)") &
       char(40),char(44) &
      ,iADigits+iADeciPl,char(46),iADeciPl,char(44) &! (sp,f__.0,
      ,char(39),char(44),char(39),char(92),char(41)           !        ','\)
     else
      write(Format1,"(a1,'sp',a1,'f',i2.2,a1,i2.2,a1,3a1,2a1)") &
       char(40),char(44) &
      ,iADigits+iADeciPl,char(46),iADeciPl,char(44) &! (sp,f__.0,
      ,char(39),char(44),char(39),char(92),char(41)           !        ','\)
   endif!(iADeciPl<10)
!  write(uD,*) Format1  !e.g.: (sp,f25.22,','\)

!  --For removing trailing zeros:
     Outlength=iADigits+iADeciPl
     write(Format2,"(a1,'a',i2.2,a1,3a1,2a1)") &
     char(40), OutLength,char(44) &               !  (a__,
    ,char(39),char(44),char(39),char(92),char(41) !       ','\)
!  write(uD,*) Format2  !e.g.: (a25,','\)

   write(uD,"('The Column and row label indices that follow'\)")
   write(uD,"(' are single-digit augmented hexadecimals.')")

!    --Export the signed coefficients:
     do nCol   = 1,nCT
       do nV   = 1,iADigits-nVT-1;write(uD,"(' '\)")                ;enddo!nV
                            write(uD,"(a1,\  )") c1cols
       do nV   = nVT,1,-1;  write(uD,"(a1,\)") AugHex(nVnC(nV,nCOl));enddo!nV
       do nV   = 1,iADeciPl;write(uD,"(' '\)")                      ;enddo!nV
                            write(uD,"(','\)")                      ;enddo!nCol
                            write(uD,"('')")   ;call Beamer(0   ,nCT,6)
     do nRow   = 1,nCT                         ;call Beamer(nRow,nCT,6)
       do nCol = 1,nCT;     write(PrintString,Format1) A(nRow,nCol) !/ADiv
!      Replace trailing 0`s with spaces
       do j=OutLength,1,-1; if(PrintString(j:j) /= "0") exit
                               PrintString(j:j)  = " "              ;enddo!j
                            write(uD,Format2) PrintString           ;enddo!nCol
                            write(uD,"(a1,\  )") c1rows
       do nV   = nVT,1,-1;  write(uD,"(a1,\)") AugHex(nVnC(nV,nRow));enddo!nV
                            write(uD,"('')")                        ;enddo!nRow
                                                                         return
End Subroutine MatrixCsvWriter
!---------------------------------------------------------------------------7 9

Subroutine ValuesSequence(iP)
!2021.03.30.1545cdt JMS- Show the values sequence for the particular .bin file.
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
  integer*4::iP           !Write enable>5: write(iP,...)
!--Internals
  integer*4::i,N,nV,nC
  character::cL*80
  !--EndDefs---------------------------
   cL='Exporting `ValuesSequenceInfo.txt` for your use.'    ;call WSF(cL,iP)
   open(unit=uD,file='ValuesSequenceInfo.txt',action='write')
    write(uD,"(79(a1,:))") (cBinFileIn(i:i),i=1,len_trim(cBinFileIn))
    write(uD,"(i3,', nVT = # of Variables Total. The orders are:' )")nVT
    write(uD,"(7(i3.1,',',:))") nOrd(1:nVT)
    do nV=1,nVT
      write(uD,"('  N, Domain of X(',i2,'):')") nV
      do N=0,nOrd(nV)
        write(uD,"(i3.1,',',f18.12)") N,X(N,nV)
      enddo!N
    enddo!nV
    write(uD,"(i6.1,',nCT = # of Coefficints Total. sequence entries:')")nCT
    write(uD, &
        "('Seq. #, X1, X2,etc, using the domain values listed above.')")
    do nC=1,nCT
      write(uD,"(i6.1,',',7(i3.1,',':) )") nC,nVnC(1:nVT,nC)
    enddo!nC
    write(uD,"(/' A(1:nCT) = Coe[1:nCT,1:nCT] * Values(1:nCT)/CoeDiv')")
    write(uD,"(/'The sequence entries above are also the respective orders')")
    write(uD,"( '  of the polynomial coefficients for synthesizing data.')")
    write(uD,"( ' X(1:nCT) = Pow[1:nCT,1:nCT] * A(1:nCT)/PowDiv')")
    write(uD,"(/'Run Polyize.exe with WhatNext = -2 to write a .csv'\)")
    write(uD,"( ' version of the .bin file.')")
    call DisclaimerEtc(uD)
   close(uD)
                                                                         return
End Subroutine ValuesSequence
!---------------------------------------------------------------------------7 9

Subroutine ExampleIputs(iP)
!2021.04.05.0605cdt JMS- Write example DataIn.txt & PolysIn.txt files.
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
  integer*4::iP           !Write enable>5: write(iP,...)
!--Internals
  integer*4::i,nV,nC1,nC2
  character::cL*80
  !--EndDefs---------------------------
   cL='Creating example files `DataIn.txt` & CoesIn.txt`.'     ;call WSF(cL,iP)
!  --Synthesize a polynomial coefficient dataset:
   CoeSeq = 0._16; CoeSeq(nCT) = 1._16; DataSeq = 0._16
!  --...and solve it:
   do nC1 = 1,nCT; DataSeq(nC1)=0._16
     do nC2 = 1,nCT; 
       DataSeq(nC1) = DataSeq(nC1)+Pow(nC1,nC2)*CoeSeq(nC2)/PowDiv
   enddo; enddo!nC1
!  --Write DataIn.txt:
   open(unit=uD,file='DataIn.txt',action='write')
     write(uD,"(79(a1,:))") (cBinFileIn(i:i),i=1,len_trim(cBinFileIn))
                      write(uD,"(i6,',',i3,', :nCT & nVT') )") nCT,nVT
     do nC1 = 1,nCT;  write(uD,"(i6,','\)") nC1
      !do nV = 1,nVT; write(uD,"(i3,','\)") nV            ;enddo!nV
       do nV = 1,nVT; write(uD,"(i3,','\)") nVnC(nV,nC1)  ;enddo!nV
                      write(uD,"(sp,f40.30)") DataSeq(nC1);enddo!nC1
       write(uD,"(a1,'(sp,f40.30)',a1,'c, :Fortran output write format.')") &
                 char(34)      ,char(34)
   close(uD)
!  --Write PolysIn.txt:
   open(unit=uD,file='CoesIn.txt',action='write')
     write(uD,"(79(a1,:))") (cBinFileIn(i:i),i=1,len_trim(cBinFileIn))
                      write(uD,"(i6,',',i3,', :nCT & nVT') )") nCT,nVT
     do nC1 = 1,nCT;  write(uD,"(i6,','\)") nC1
       do nV = 1,nVT; write(uD,"(i3,','\)") nV            ;enddo!nV
                      write(uD,"(sp,f40.30)") CoeSeq(nC1);enddo!nC1
       write(uD,"(a1,'(sp,f40.30)',a1,'c, :Fortran output write format.')") &
                 char(34)      ,char(34)
   close(uD)
                                                                         return
End Subroutine ExampleIputs
!---------------------------------------------------------------------------7 9

Subroutine DataInToCoesOut(iP)
!2021.04.05.0605cdt JMS- Read DataIn.txt and write CoesOut.txt
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
  integer*4::iP           !Write enable>5: write(iP,...)
!--Internals
  integer*4::i,j,nV,nC1,nC2,nCTL,nVTL
  character::cL*80
  character::Format1*80
  !--EndDefs---------------------------
   cL='Process your `DataIn.txt` -> `CoesOut.txt`.'            ;call WSF(cL,iP)
!  --CoeSeq() = Coe[,] * DataSeq():
   cL=Char(0)
   open(unit=uD,file='DataIn.txt',action='read')
     read(uD,*) cL(1:nNameChars)   ;write(6,*) cL
     read(uD,*) nCTL,nVTL          ;write(6,*) 'nCT=',nCTL,' nVT=',nVTL
     if((nCT/=nCTL).or.(nVT/=nVTL)) return
!    --Import the data:
     DataSeq(nC1)=0._16
     do nC1 = 1,nCT; read(uD,*) nC2,(i,j=1,nVT),DataSeq(nC2)         ;enddo!nC1
     read(uD,*) Format1; write(6,*) Format1
   close(uD)
!  --- compute CoeSeq:
   CoeSeq=0._16
   do nC1=1,nCT
     do nC2 = 1,nCT
     CoeSeq(nC1) = CoeSeq(nC1)+Coe(nC1,nC2)*DataSeq(nC2)/CoeDiv
   enddo; enddo!nC1
!  --Write CoesOut.txt:
   open(unit=uD,file='CoesOut.txt',action='write')
     write(uD,"(79(a1,:))") (cBinFileIn(i:i),i=1,len_trim(cBinFileIn))
                      write(uD,"(i6,',',i3,', :nCT & nVT') )") nCT,nVT
     do nC1 = 1,nCT;  write(uD,"(i6,','\)") nC1
       do nV = 1,nVT; write(uD,"(i3,','\)") nVnC(nV,nC1)  ;enddo!nV
                      write(uD,Format1) CoeSeq(nC1);enddo!nC1
       write(uD,*)  Format1
   close(uD)
                                                                         return
End Subroutine DataInToCoesOut
!---------------------------------------------------------------------------7 9

Subroutine CoesInToDataOut(iP)
!2021.04.05.0605cdt JMS- Read DataIn.txt and write CoesOut.txt
 use PolyizeDef
!--End Globals
 implicit none
 !--Arguments
  integer*4::iP           !Write enable>5: write(iP,...)
!--Internals
  integer*4::i,j,nV,nC1,nC2,nCTL,nVTL
  character::cL*80
  character::Format1*80
  !--EndDefs---------------------------
   cL='Process your `CoesIn.txt` -> `DataOut.txt`.'            ;call WSF(cL,iP)
!  --CoeSeq() = Coe[,] * DataSeq():
   cL=Char(0)
   open(unit=uD,file='CoesIn.txt',action='read')
     read(uD,*) cL(1:nNameChars)   ;write(6,*) cL
     read(uD,*) nCTL,nVTL          ;write(6,*) 'nCT=',nCTL,' nVT=',nVTL
     if((nCT/=nCTL).or.(nVT/=nVTL)) return
!    --Import the data:
     CoeSeq(nC1)=0._16
     do nC1 = 1,nCT; read(uD,*) nC2,(i,j=1,nVT),CoeSeq(nC2)         ;enddo!nC1
     read(uD,*) Format1; write(6,*) Format1
   close(uD)
!  --- compute DataSeq:
   DataSeq=0._16
   do nC1=1,nCT
     do nC2 = 1,nCT
     DataSeq(nC1) = DataSeq(nC1)+Pow(nC1,nC2)*CoeSeq(nC2)/PowDiv
   enddo; enddo!nC1
!  --Write CoesOut.txt:
   open(unit=uD,file='DataOut.txt',action='write')
     write(uD,"(79(a1,:))") (cBinFileIn(i:i),i=1,len_trim(cBinFileIn))
                      write(uD,"(i6,',',i3,', :nCT & nVT') )") nCT,nVT
     do nC1 = 1,nCT;  write(uD,"(i6,','\)") nC1
      !do nV = 1,nVT; write(uD,"(i3,','\)") nV            ;enddo!nV
       do nV = 1,nVT; write(uD,"(i3,','\)") nVnC(nV,nC1)  ;enddo!nV
                      write(uD,Format1) DataSeq(nC1);enddo!nC1
       write(uD,*)  Format1
   close(uD)
                                                                         return
End Subroutine CoesInToDataOut
!---------------------------------------------------------------------------7 9
Subroutine CoefficientCount(iP)
!2021.04.06.0555cdt JMS- # of coeff`s of even-order multi-variable Polynomials
 use PolyizeDef, only:uD
 implicit none
 !--Arguments
  integer*4 ::iP           !Write enable>5: write(iP,...)
 !--Internals
  integer*4 ::nMax=7,j,nOrder(10)=1,nCh,iUsed,nLine
  integer*4 ::i1,i2,i3,i4,i5,i6,i7
  integer*4 ::j1,j2,j3,j4,j5,j6,j7
  character::cL*100
  !--EndDefs-----------------------------------------------
!  --Write DataIn.txt:
   cL='Write the `Coefficient Count Table`.'                   ;call WSF(cL,iP)
   open(unit=uD,file='CoefficientCount.txt',action='write')
   cL=''c ;write(uD,*) CL
   cL= &
   '    Number of polynomial coefficients <= 9999'// &
   '  for 7 variables up to order 20'c
   write(uD,*) CL
   cL= &
   '            Order of v1 = 0    2    4    6    8|'// &
   '  10   12   14   16   18   20'c
   write(uD,*) CL
   cL= &
   '                      ----------------- <-exact|unscaled->'// &
   ' ------------------'c
   write(uD,*) CL
                              nLine=1
   do i1=0,20,2                ; j1 = i1+1;
     do i2=i1,20,2             ; j2 = i2+1;
       do i3=i2,20,2           ; j3 = i3+1;
         do i4=i3,20,2         ; j4 = i4+1;
           do i5=i4,20,2       ; j5 = i5+1;
             do i6=i5,20,2     ; j6 = i6+1;
                                j  = j1*j2*j3*j4*j5*j6
                             if(J>9999) exit
                 cL=char(0);  iUsed = 0;           nCh = 22
                 write(cL(1:22),"(i3,1x,6i3.0\)") nLine,i1,i2,i3,i4,i5,i6
                                 if(nLine==  1) cL(17:22) = 'V2 = 0'
                                 if(nLine== 11) cL(14:19) = 'V3 = 0'
                                 if(nLine== 66) cL(11:16) = 'V4 = 0'
                                 if(nLine==132) cL( 8:13) = 'V5 = 0'
                                 if(nLine==161) cL( 5:10) = 'V6 = 0'
                                 if(nLine==171) cL( 4: 7) = 'V7=0'
               do i7=2,i6,2;              write(cL(nCh+1:nCh+5),"('     '\)")
                                                   nCh = nCh+5        ;enddo!i7
               do i7=i6,20,2;  j7 = i7+1;
                                  j  = j1*j2*j3*j4*j5*j6*j7
                               if(J>9999) exit
                               iUsed = iUsed+1
                                          write(cL(nCh+1:nCh+5),"(i5\)") j
                                                   nCh = nCh+5
               enddo!i7
                            if(iUsed==0) exit
                              nLine=nLine+1
                                                      cL(48:48)='|'
                                          write(uD,*) CL
             enddo!i6
           enddo!i5
         enddo!i4
       enddo!i3
     enddo!i2
   enddo!i1
   cL= &
   '                      ----------------- <-exact|unscaled->'// &
   ' ------------------'c
   write(uD,*) CL
   cL=''c ;write(uD,*) CL
   call DisclaimerEtc(uD)
   close(uD)
                                                                         return
End Subroutine CoefficientCount
!---------------------------------------------------------------------------7 9

Subroutine DisclaimerEtc(iP)
!2021.04.01.0855dt JMS- Disclaimer, etc.
!Elapsed is updated first,
!       so using the same argument twice results in returning the DaTime value.
!--Arguments
 implicit none
  integer*4::iP           !Write enable>5: write(iP,...)
 !--Internals
  character::cL*80
  !--EndDefs-----------------------------------------------
 cL=""                                                         ;call WSF(cL,iP)
 cL="   Link: http://ftp.setterholm.com/ExactInversePolynomials/Polygen.zip"c
                                                                call WSF(cL,iP)
 cL="Analyst: Jeff Setterholm  Lakeville MN 55044 USA   Tuesday 2020.04.06"c
                                                                call WSF(cL,iP)
 cL=""                                                         ;call WSF(cL,iP)
 cL="  ********, Polyize.exe is post-copyright i.e.:FREE ,********"c
                                                                call WSF(cL,iP)
 cL=""                                                         ;call WSF(cL,iP)
 cL="  My legal disclaimer:"c                                  ;call WSF(cL,iP)
 cL="  ***********************************************************"c
                                                                call WSF(cL,iP)
 cL="  ********,  Individual cognition is always flawed  ,********"c
                                                                call WSF(cL,iP)
 cL="  ********,          including yours & mine.        ,********"c
                                                                call WSF(cL,iP)
 cL="  ********,                 - So: -                 ,********"c
                                                                call WSF(cL,iP)
 cL="  ********,    Use these results at your own risk.  ,********"c
                                                                call WSF(cL,iP)
 cL="  ***********************************************************"c
                                                                call WSF(cL,iP)
 cL="           Mitigate malfunctions. Nurture synergies."c
                                                                call WSF(cL,iP)
 cL=""                                                         ;call WSF(cL,iP)
                                                                         return
End Subroutine DisclaimerEtc
!---------------------------------------------------------------------------7 9

