home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 February / PCWK0297.iso / technika / nnmodel / datamat.c < prev    next >
C/C++ Source or Header  |  1996-04-18  |  18KB  |  640 lines

  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #include "nndefs.h"
  8. #include "datamat.h"
  9.  
  10. #define ARRAYCHUNK 100
  11.  
  12.     extern union {
  13.         float f;
  14.         long l;
  15.         } MissingUnion;
  16. #define MISSING (MissingUnion.f)
  17.     void Logit(const char* fmt, ...);
  18.  
  19.     void dump (const char *buf, int count);
  20.  
  21. /* Record type defines ****
  22.     'T' or 't' or ' ' rectype=0 Training record
  23.     'C' or 'c'        rectype=0 Training record Center point 
  24.     'S' or 's'        rectype=0 Training record Star point
  25.     'F' or 'f'        rectype=0 Training record Factorial point
  26.     'M' or 'm'        rectype=0 Training record MultiLevel point
  27.     'X' or 'x'        rectype=0 Training record Simplex point
  28.  
  29.     'V' or 'v'        rectype=1 Verification & test record
  30.  
  31.     'D' or 'd'        rectype=2 Deleted (but use for scaling)
  32.     'R' or 'r'          rectype=2 Rejected (don't suggest,use in scale)
  33.  
  34.     'E' or 'e'        rectype=3 Excluded (not used in scaling)
  35.     '*'               rectype=4 Comment record
  36.     'L' or 'l'        rectype=5 Field label record
  37.     'U' or 'u'        rectype=6 Units record
  38. */
  39.  
  40.  
  41. /*
  42.     static char BASED_CODE msg1[] = "Out of memory in CDataMat line no=%d";
  43.     static char BASED_CODE msg2[] = "Invalid record type in data file <%x> record=%d";
  44.     static char BASED_CODE msg3[] = "Error while importing design matrix\nlast record D%02d";
  45.     static char BASED_CODE msg4[] = "Error number of columns don't agree record=%d";
  46.     static char BASED_CODE msg5[] = "Can't open file <%s>";
  47.     static char BASED_CODE msg7[] = "Calculated fields not suppported";
  48.     static char BASED_CODE msg8[] = "No data loaded into training or test maxrix due to lags";
  49.     static char BASED_CODE msg9[] = "Skipping record(s) with bad record types";
  50.     static char BASED_CODE msg10[] = "Rejecting - Bad Scale on record %d field=%d val=%f\n";
  51. */
  52.  
  53.     void ToUpper (char *s);
  54.     int ChkClip (float f, float hi, float lo);
  55.  
  56. // Call implement serial macro for all the classes declared
  57. // in datamat.h
  58.  
  59.  
  60. void ZeroAll(DATAMAT *pD) {
  61.  
  62. #ifdef VERBOSE
  63.     Logit ("Zeroall\n");
  64. #endif
  65.     pD->m_version = REVLEVEL;
  66.     pD->m_numtests = 0 ;
  67.     pD->m_numcols = 0 ;
  68.     pD->m_numrows = 0 ;
  69.     pD->m_ninputs = 0 ;
  70.     pD->m_maxrows = 0;
  71.     pD->m_maxtests = 0 ;
  72.     pD->m_noutputs = 0 ;
  73.     pD->m_maxrows = pD->m_rawcols = pD->m_rawrows = 0;
  74.     pD->m_istate = NFobject_exists;
  75.  
  76.     pD->m_icrossref = NULL;
  77.     pD->m_ocrossref = NULL;
  78.     pD->m_coldesc = NULL;
  79.     pD->m_rowdesc = NULL;
  80.     pD->m_icoldesc = NULL;
  81.     pD->m_ocoldesc = NULL;
  82.     pD->m_iarray = NULL;
  83.     pD->m_oarray = NULL;
  84.     pD->m_itarray = NULL;
  85.     pD->m_otarray = NULL;
  86.     pD->m_title[0] = pD->m_desc[0] = pD->m_parfname[0] = pD->m_rawfname[0] = 0;
  87.  
  88.  
  89. }              
  90. // Null Constructor
  91.  
  92. DATAMAT *DCreateDataMat()
  93. {             
  94.     DATAMAT *pD;
  95.     pD = (DATAMAT*) malloc (sizeof(DATAMAT));
  96.     
  97. #ifdef VERBOSE
  98.     Logit ("CDataMat null constructor\n");
  99. #endif
  100.     ZeroAll(pD);        
  101.     return pD;
  102. }
  103.  
  104. void ZeroColDesc(DATAMAT *pD, int num,COL_DESC* desc)
  105. {
  106.     int i;
  107.     for (i=0;i<num;i++) {
  108.         desc[i].fscale =
  109.         desc[i].foffset = 0.0f;
  110.         desc[i].max = 0.0f;
  111.         desc[i].min = 0.0f;
  112.         desc[i].fieldtype=0;
  113.         desc[i].cliphi = MISSING;
  114.         desc[i].cliplo = MISSING;
  115.         desc[i].colwidth = 90;
  116.         desc[i].flag = 0;
  117.         desc[i].col_usage = 'N';
  118.         strcpy (&desc[i].format[0],"%s");
  119.         desc[i].vlab[0]=0;
  120.         desc[i].units[0]=0;
  121.         if (pD->m_icrossref!=NULL) pD->m_icrossref[i] = pD->m_ocrossref[i] = -1;
  122.     }
  123. }
  124.  
  125.  
  126. //Destruction
  127. void DDeleteDataMat(DATAMAT *pD)
  128. {
  129.  
  130. #ifdef VERBOSE
  131.     Logit ("CDataMat DeleteContents istate=%lx\n",pD->m_istate);
  132. #endif
  133.     if (pD->m_istate & NFnum_col_known) {
  134.         free  (pD->m_coldesc);
  135.         free (pD->m_icrossref);
  136.         free (pD->m_ocrossref);
  137.     }
  138.  
  139.     free (pD->m_icoldesc);
  140.     free (pD->m_ocoldesc);
  141.     
  142. #ifdef VERBOSE
  143.     Logit ("CDataMat Delete Arrays\n");
  144. #endif
  145.     if (pD->m_istate&NFtrainmat_loaded) {
  146.         if (pD->m_ninputs) 
  147.             free_2d_floats (pD->m_iarray,pD->m_ninputs);
  148.         if (pD->m_noutputs) 
  149.             free_2d_floats (pD->m_oarray,pD->m_noutputs);
  150.     }
  151.     if (pD->m_istate&NFtestmat_loaded) {
  152.         if (pD->m_ninputs) 
  153.             free_2d_floats (pD->m_itarray,pD->m_ninputs);
  154.         if (pD->m_noutputs) 
  155.             free_2d_floats (pD->m_otarray,pD->m_noutputs);
  156.     }
  157.  
  158.     ZeroAll(pD);
  159. }
  160.  
  161. void RemoveTestMatrix(DATAMAT *pD)
  162. {
  163.     if (pD->m_istate&NFtestmat_loaded) {
  164.         if (pD->m_ninputs) free_2d_floats (pD->m_itarray,pD->m_ninputs);
  165.         if (pD->m_noutputs) free_2d_floats (pD->m_otarray,pD->m_noutputs);
  166.     }
  167.  
  168.     pD->m_istate &= ~NFtestmat_loaded;
  169.     pD->m_itarray = NULL;
  170.     pD->m_otarray = NULL;
  171.     pD->m_numtests=0;    
  172. }
  173.  
  174. void RemoveMatrix(DATAMAT *pD)
  175. {
  176.     if (pD->m_istate&NFtrainmat_loaded) {
  177.         if (pD->m_ninputs) free_2d_floats (pD->m_iarray,pD->m_ninputs);
  178.         if (pD->m_noutputs) free_2d_floats (pD->m_oarray,pD->m_noutputs);
  179.     }
  180.     if (pD->m_istate&NFtestmat_loaded) {
  181.         if (pD->m_ninputs) free_2d_floats (pD->m_itarray,pD->m_ninputs);
  182.         if (pD->m_noutputs) free_2d_floats (pD->m_otarray,pD->m_noutputs);
  183.     }
  184.  
  185.     pD->m_istate &= ~NFtestmat_loaded;
  186.     pD->m_istate &= ~NFtrainmat_loaded;
  187.     pD->m_istate &= ~NFunscaled_loaded;
  188.     pD->m_iarray = NULL;
  189.     pD->m_oarray = NULL;
  190.     pD->m_itarray = NULL;
  191.     pD->m_otarray = NULL;
  192.     
  193. }
  194.  
  195.  
  196.  
  197. //Attributes
  198.     //member functions to modify the protected member variables
  199.  
  200. float DGetInputVal(DATAMAT *pD, int row, int col ) {
  201.     return pD->m_iarray[col][row];
  202. }
  203. float DGetOutputVal(DATAMAT *pD, int row, int col ) {
  204.     return pD->m_oarray[col][row];
  205. }
  206. float DGetInputTVal(DATAMAT *pD, int row, int col ) {
  207.     return pD->m_itarray[col][row];
  208. }
  209. float DGetOutputTVal(DATAMAT *pD, int row, int col ) {
  210.     return pD->m_otarray[col][row];;
  211. }
  212. void DSetInputVal(DATAMAT *pD, int row, int col, float val ) {
  213.     pD->m_iarray[col][row] = val;
  214. }
  215. void DSetInputTVal(DATAMAT *pD, int row, int col, float val ) {
  216.     pD->m_itarray[col][row] = val;
  217. }
  218.  
  219. void DSetOutputVal(DATAMAT *pD, int row, int col, float val ) {
  220.     pD->m_oarray[col][row] = val;
  221. }
  222. void DSetOutputTVal(DATAMAT *pD, int row, int col, float val ) {
  223.     pD->m_otarray[col][row] = val;
  224. }
  225.  
  226. float DRescale(DATAMAT *pD, float f,char C,int ix) {
  227.     if (f==MISSING) return f;
  228.     if (C=='I') {
  229.         f /= pD->m_icoldesc[ix].fscale;
  230.         f -= pD->m_icoldesc[ix].foffset;
  231.     }
  232.     if (C=='O') {
  233.         f /= pD->m_ocoldesc[ix].fscale;
  234.         f -= pD->m_ocoldesc[ix].foffset;
  235.     }             
  236.     return f;
  237. }
  238.  
  239. float DScale(DATAMAT *pD, float f,char C,int ix) {
  240.     if (C=='I') {
  241.         f += pD->m_icoldesc[ix].foffset;
  242.         f *= pD->m_icoldesc[ix].fscale;
  243.     }
  244.     if (C=='O') {
  245.         f += pD->m_ocoldesc[ix].foffset;
  246.         f *= pD->m_ocoldesc[ix].fscale;
  247.     }
  248.     return f;
  249. }
  250.  
  251.  
  252. char * RescaleFmt(DATAMAT *pD,float f,char C,int ix) {
  253.     float val;     
  254.     char buf[40];
  255.     
  256.     if (f==MISSING) return " . ";
  257.     val = DRescale(pD,f,C,ix);
  258.     if (C=='O') {
  259.         sprintf (buf,&pD->m_ocoldesc[ix].format[0],val);
  260.         strncpy (&pD->m_ocoldesc[ix].convstr[0],buf,20);
  261.         pD->m_ocoldesc[ix].convstr[19]=0;
  262.         return &pD->m_ocoldesc[ix].convstr[0];
  263.     }
  264.     if (C=='I') {
  265.         sprintf (buf,&pD->m_icoldesc[ix].format[0],val);
  266.         strncpy (&pD->m_icoldesc[ix].convstr[0],buf,20);
  267.         pD->m_icoldesc[ix].convstr[19]=0;
  268.         return &pD->m_icoldesc[ix].convstr[0];
  269.     }
  270.     return "BadC";
  271. }
  272.  
  273.  
  274. void DReCalcScalingFactor(COL_DESC *cold, int cols)
  275. {
  276.     int i;
  277.     float range;
  278.     
  279.     for (i=0;i<cols;i++) {
  280.         if (cold[i].fieldtype==FIELDTYPE_FLOAT) {
  281.             range = cold[i].max-cold[i].min;
  282.             if (cold[i].min < 0.0f) cold[i].foffset = (float) fabs(cold[i].min);
  283.             else cold[i].foffset = -cold[i].min;
  284.             if (range!=0.0f) cold[i].fscale = 1.0f/range;
  285.             else {
  286.                 cold[i].fscale=1.0f;
  287.                 cold[i].foffset += .5f;
  288.             }
  289.             cold[i].fscale *= .6f;
  290.             cold[i].foffset += ((float)fabs(range) * .333333f);
  291.         }
  292.     }
  293.     return;
  294. }
  295.  
  296. int dtransl(char *cdummy)
  297. {
  298.     int val=0;
  299.     if (cdummy[0] == 'D') {
  300.         sscanf(&cdummy[1],"%d",&val);
  301.         if (val > 8) return -1;
  302.         return val;
  303.     }
  304.     if (cdummy[0] == 'M') return 0;
  305.     if (cdummy[0] == 'T') return 1000;
  306.     return -1;
  307. }
  308.  
  309. int DImportDataMat(DATAMAT *pD, FILE *fd) {
  310.     int i,numtrain,numtest;
  311.     char cdummy[128];
  312.     int sel,stat,lastsel;
  313.     float f;                   
  314.     time_t ttime;
  315.     sel=0;
  316.                       
  317. #ifdef VERBOSE
  318.     Logit("Start import DM\n");
  319. #endif
  320.     numtrain = numtest = 0;
  321. top:
  322.     stat = fscanf (fd,"%s",&cdummy);
  323.     if (stat==EOF) {
  324. #ifdef VERBOSE
  325.         Logit("Finished import DM\n");
  326. #endif
  327.         return 0;
  328.     }
  329.     lastsel = sel;
  330.     sel = dtransl(cdummy);
  331. //    Logit("Reading %s\n",cdummy);
  332.     switch (sel) {
  333.     default: //error
  334.         goto errorexit;
  335.         break;
  336.     case 0: //training data
  337.         for(i=0;i<pD->m_ninputs;i++) {
  338.             fscanf (fd,"%e",&f);
  339.             DSetInputVal(pD,numtrain,i,DScale(pD,f,'I',i));
  340.         }
  341.         for(i=0;i<pD->m_noutputs;i++) {
  342.             fscanf (fd,"%e",&f);
  343.             DSetOutputVal(pD,numtrain,i,DScale(pD,f,'O',i));
  344.         }                        
  345.         numtrain++;
  346.         break;
  347.     case 1000: // test data
  348.         for(i=0;i<pD->m_ninputs;i++) {
  349.             fscanf (fd,"%e",&f);
  350.             DSetInputTVal(pD,numtest,i,DScale(pD,f,'I',i));
  351.         }
  352.         for(i=0;i<pD->m_noutputs;i++) {
  353.             fscanf (fd,"%e",&f);
  354.             DSetOutputTVal(pD,numtest,i,DScale(pD,f,'O',i));
  355.         }                        
  356.         numtest++;
  357.         break;
  358.     case 1:
  359.         fscanf (fd,"%lu %d %d %d %d %d %d %d\n",&pD->m_istate,&pD->m_numcols,&pD->m_numrows,
  360.             &pD->m_ninputs,&pD->m_noutputs,&pD->m_rawrows,&pD->m_rawcols,&pD->m_total);
  361.         if (pD->m_istate&NFnum_col_known) {
  362.             pD->m_coldesc = (COL_DESC*) malloc (sizeof(COL_DESC)*pD->m_numcols);
  363.             pD->m_icrossref = (int*) malloc (sizeof(int)*pD->m_numcols);
  364.             pD->m_ocrossref = (int*) malloc (sizeof(int)*pD->m_numcols);
  365.             for (i=0;i<pD->m_numcols;i++) {
  366.                 pD->m_icrossref[i]=0;
  367.                 pD->m_ocrossref[i]=0;
  368.             }
  369.             for (i=0;i<pD->m_numcols;i++) {
  370.                 pD->m_coldesc[i].fscale = 0;
  371.                 pD->m_coldesc[i].foffset = 0; 
  372.                 pD->m_coldesc[i].cliphi = pD->m_coldesc[i].cliplo = MISSING;
  373.                 pD->m_coldesc[i].max = 0;
  374.                 pD->m_coldesc[i].min = 0;
  375.                 pD->m_coldesc[i].flag = 0;
  376.                 pD->m_coldesc[i].fieldtype = 0;
  377.                 pD->m_coldesc[i].col_usage = 'U';
  378.                 pD->m_coldesc[i].format[0] = 0;
  379.                 pD->m_coldesc[i].vlab[0] = 0;
  380.                 pD->m_coldesc[i].units[0] = 0;
  381.                 pD->m_coldesc[i].colwidth = 90;
  382.             }
  383.  
  384.         }
  385.         pD->m_istate = NFobject_exists | NFnum_col_known | 
  386.                     NFtrainmat_loaded | NFi_o_col_known;
  387.         if (pD->m_istate&NFtrainmat_loaded) {
  388.             pD->m_icoldesc = (COL_DESC*) malloc (sizeof(COL_DESC)*pD->m_ninputs);
  389.             pD->m_ocoldesc = (COL_DESC*) malloc (sizeof(COL_DESC)*pD->m_noutputs);
  390.             if (pD->m_numrows) {
  391.                 pD->m_iarray = alloc_2d_floats (pD->m_ninputs,pD->m_numrows);
  392.                 pD->m_oarray = alloc_2d_floats (pD->m_noutputs,pD->m_numrows);
  393.             } else pD->m_istate &= ~NFtrainmat_loaded;
  394.         }
  395.         break;
  396.     case 2:      
  397.         fscanf (fd,"%s",cdummy);
  398.         strncpy (pD->m_title,cdummy,MAXCSTRING);
  399.         fscanf (fd,"%s",cdummy);
  400.         strncpy (pD->m_desc,cdummy,MAXCSTRING);
  401.         fscanf (fd,"%s",cdummy);
  402.         strncpy (pD->m_rawfname,cdummy,MAXCSTRING);
  403.         fscanf (fd,"%s",cdummy);
  404.         strncpy (pD->m_parfname,cdummy,MAXCSTRING);
  405.         fscanf (fd,"%ld",&ttime);                     
  406. //        if (ttime) pD->m_creation = ttime;
  407. //        else pD->m_creation = CTime::GetCurrentTime();
  408.  
  409.         pD->m_istate |= (NFtitle_known    | NFdesc_known |
  410.                      NFraw_file_known );
  411.         break;
  412.     case 3:
  413.         fscanf (fd,"%d",&i);
  414.         fscanf (fd,"%d %d %f %f %f %f %c %s %s",
  415.             &pD->m_coldesc[i].flag,
  416.             &pD->m_coldesc[i].fieldtype,
  417.             &pD->m_coldesc[i].fscale,
  418.             &pD->m_coldesc[i].foffset,
  419.             &pD->m_coldesc[i].max,
  420.             &pD->m_coldesc[i].min,
  421.             &pD->m_coldesc[i].col_usage,
  422.             &pD->m_coldesc[i].format,
  423.             &pD->m_coldesc[i].vlab);
  424.  
  425.         pD->m_coldesc[i].units[0] = 0;
  426.         pD->m_coldesc[i].cliphi = pD->m_coldesc[i].cliplo = MISSING;
  427.         pD->m_coldesc[i].colwidth = 90;
  428.         pD->m_istate |= NFcol_usage_known;
  429.         break;
  430.     case 4:
  431.         for (i=0;i<pD->m_numcols;i++) fscanf(fd,"%d",&pD->m_icrossref[i]);
  432.         break;
  433.     case 5:
  434.         for (i=0;i<pD->m_numcols;i++) fscanf(fd,"%d",&pD->m_ocrossref[i]);
  435.         break;
  436.     case 6:
  437.         fscanf (fd,"%d",&i);
  438.         fscanf (fd,"%d %d %f %f %f %f %c %s %s",
  439.             &pD->m_icoldesc[i].flag,
  440.             &pD->m_icoldesc[i].fieldtype,
  441.             &pD->m_icoldesc[i].fscale,
  442.             &pD->m_icoldesc[i].foffset,
  443.             &pD->m_icoldesc[i].max,
  444.             &pD->m_icoldesc[i].min,
  445.             &pD->m_icoldesc[i].col_usage,
  446.             &pD->m_icoldesc[i].format,
  447.             &pD->m_icoldesc[i].vlab);
  448.         pD->m_icoldesc[i].units[0] = 0;
  449.         pD->m_icoldesc[i].colwidth = 90;
  450.         pD->m_icoldesc[i].cliphi = pD->m_icoldesc[i].cliplo = MISSING;
  451.         pD->m_istate |= NFcol_usage_known | NFi_o_col_known;
  452.         break;
  453.     case 7:
  454.         fscanf (fd,"%d",&i);
  455.         fscanf (fd,"%d %d %f %f %f %f %c %s %s",
  456.             &pD->m_ocoldesc[i].flag,
  457.             &pD->m_ocoldesc[i].fieldtype,
  458.             &pD->m_ocoldesc[i].fscale,
  459.             &pD->m_ocoldesc[i].foffset,
  460.             &pD->m_ocoldesc[i].max,
  461.             &pD->m_ocoldesc[i].min,
  462.             &pD->m_ocoldesc[i].col_usage,
  463.             &pD->m_ocoldesc[i].format,
  464.             &pD->m_ocoldesc[i].vlab);
  465.         pD->m_ocoldesc[i].units[0] = 0;
  466.         pD->m_ocoldesc[i].colwidth = 90;
  467.         pD->m_ocoldesc[i].cliphi = pD->m_ocoldesc[i].cliplo = MISSING;
  468.         pD->m_istate |= NFcol_usage_known | NFi_o_col_known;
  469.         break;
  470.     case 8: //NUMBER OF TEST ROWS
  471.         fscanf(fd,"%d",&pD->m_numtests);
  472.         if (pD->m_numtests) {
  473.             pD->m_itarray = alloc_2d_floats (pD->m_ninputs,pD->m_numtests);
  474.             pD->m_otarray = alloc_2d_floats (pD->m_noutputs,pD->m_numtests);
  475.             pD->m_istate |= NFtestmat_loaded;                     
  476.         }
  477.         break;
  478.     }                          
  479.     goto top;
  480.  
  481. errorexit:
  482.     return -1;
  483. }
  484.  
  485. char * DRescaleFmt(DATAMAT *pD, float f,char C,int ix) {
  486.     float val;     
  487.     char buf[40];
  488.     
  489.     if (f==MISSING) return " . ";
  490.     val = DRescale(pD,f,C,ix);
  491.  
  492.     if (C=='O') {
  493.         sprintf (buf,&pD->m_ocoldesc[ix].format[0],val);
  494.         strncpy (&pD->m_ocoldesc[ix].convstr[0],buf,20);
  495.         pD->m_ocoldesc[ix].convstr[19]=0;
  496.         return &pD->m_ocoldesc[ix].convstr[0];
  497.     }
  498.     if (C=='I') {
  499.         sprintf (buf,&pD->m_icoldesc[ix].format[0],val);
  500.         strncpy (&pD->m_icoldesc[ix].convstr[0],buf,20);
  501.         pD->m_icoldesc[ix].convstr[19]=0;
  502.         return &pD->m_icoldesc[ix].convstr[0];
  503.     }
  504.     return "BadC";
  505. }
  506.  
  507. void printclip (FILE *fd,float hi, float lo) { 
  508.     if (hi==MISSING) fprintf (fd," cliphi=MISSING");
  509.     else fprintf (fd," cliphi=%f",hi);
  510.     if (lo==MISSING) fprintf (fd," cliplo=MISSING\n");
  511.     else fprintf (fd," cliplo=%f\n",lo);
  512. }
  513.  
  514. void DumpDataMat(DATAMAT *pD,FILE *fd) {
  515.     int i,j;                                  
  516.     int nodata;
  517.     int maxnum;
  518.  
  519.     static char fmt1[] =
  520. "Dump of DataMat istate=%lx title=%s\ndesc=%s\nraw=%s\nparfname=%s\
  521. \nnumcols=%d numrows=%d numtests=%d nin=%d nout=%d rawrows=%d rawcols=%d\
  522. \nmaxrows=%d maxtests=%d sep=%d\n";
  523.  
  524.     static char fmt2[] = 
  525. "flag=%d ftype=%d fscale=%f foffset=%f max=%f min= %f usage=%c format=<%s> vlab=<%s> units=<%s> colw=%d";
  526.  
  527.     static char fmt3[] = 
  528. "numfact=%d numresp=%d dtype=%d dsel=%d scope=%d phase=%d ncenter=%d\nmode=%d scale=%f\n";
  529.  
  530.     fprintf (fd,fmt1,pD->m_istate,(const char *)pD->m_title,(const char *)pD->m_desc,
  531.         (const char *)pD->m_rawfname,(const char *)pD->m_parfname,
  532.         pD->m_numcols,pD->m_numrows,pD->m_numtests,
  533.         pD->m_ninputs,pD->m_noutputs,pD->m_rawrows,pD->m_rawcols,pD->m_maxrows,pD->m_maxtests,pD->m_sep);
  534.     if ((pD->m_numcols<1) || (pD->m_numrows<0)) {
  535.         fprintf (fd,"Bad DM\n");
  536.         return;
  537.     }
  538.  
  539.     if (pD->m_istate&NFnum_col_known) {
  540.         fprintf (fd,"icross = ");
  541.         for (i=0;i<pD->m_numcols;i++) 
  542.             fprintf (fd,"%02d ",pD->m_icrossref[i]);
  543.         fprintf (fd,"\nocross = ");
  544.         for (i=0;i<pD->m_numcols;i++) 
  545.             fprintf (fd,"%02d ",pD->m_ocrossref[i]);
  546.         fprintf (fd,"\n");
  547.     }
  548.     if (pD->m_coldesc) {
  549.         for (i=0;i<pD->m_numcols;i++) {
  550.             fprintf (fd,fmt2,
  551.                 pD->m_coldesc[i].flag,
  552.                 pD->m_coldesc[i].fieldtype,
  553.                 pD->m_coldesc[i].fscale,
  554.                 pD->m_coldesc[i].foffset,
  555.                 pD->m_coldesc[i].max,
  556.                 pD->m_coldesc[i].min,
  557.                 pD->m_coldesc[i].col_usage,
  558.                 pD->m_coldesc[i].format,
  559.                 pD->m_coldesc[i].vlab,
  560.                 pD->m_coldesc[i].units,
  561.                 pD->m_coldesc[i].colwidth);
  562.             printclip (fd,pD->m_coldesc[i].cliphi,pD->m_coldesc[i].cliplo);
  563.         
  564.         }
  565.     }
  566.  
  567.     fprintf(fd,"\n");
  568.     for (i=0;i<pD->m_ninputs;i++) {
  569.         fprintf (fd,fmt2,
  570.             pD->m_icoldesc[i].flag,
  571.             pD->m_icoldesc[i].fieldtype,
  572.             pD->m_icoldesc[i].fscale,
  573.             pD->m_icoldesc[i].foffset,
  574.             pD->m_icoldesc[i].max,
  575.             pD->m_icoldesc[i].min,
  576.             pD->m_icoldesc[i].col_usage,
  577.             pD->m_icoldesc[i].format,
  578.             pD->m_icoldesc[i].vlab,
  579.             pD->m_icoldesc[i].units,
  580.             pD->m_icoldesc[i].colwidth);
  581.         printclip (fd,pD->m_icoldesc[i].cliphi,pD->m_icoldesc[i].cliplo);
  582.     }
  583.     for (i=0;i<pD->m_noutputs;i++) {
  584.         fprintf (fd,fmt2,
  585.             pD->m_ocoldesc[i].flag,
  586.             pD->m_ocoldesc[i].fieldtype,
  587.             pD->m_ocoldesc[i].fscale,
  588.             pD->m_ocoldesc[i].foffset,
  589.             pD->m_ocoldesc[i].max,
  590.             pD->m_ocoldesc[i].min,
  591.             pD->m_ocoldesc[i].col_usage,
  592.             pD->m_ocoldesc[i].format,
  593.             pD->m_ocoldesc[i].vlab,
  594.             pD->m_ocoldesc[i].units,
  595.             pD->m_ocoldesc[i].colwidth);
  596.         printclip (fd,pD->m_ocoldesc[i].cliphi,pD->m_ocoldesc[i].cliplo);
  597.     }
  598.     nodata =1;
  599.  
  600.     if (pD->m_istate&NFtrainmat_loaded) {
  601.         nodata = 0;
  602.         maxnum = pD->m_numrows;
  603. //        if (maxnum > 10) maxnum=10;
  604.  
  605.         for(i=0;i<pD->m_ninputs;i++) fprintf (fd,"\t%s",pD->m_icoldesc[i].vlab);
  606.         fprintf (fd," ==>");
  607.         for(i=0;i<pD->m_noutputs;i++) fprintf (fd,"\t%s",pD->m_ocoldesc[i].vlab);
  608.         fprintf (fd,"\n");        
  609.  
  610.         for (j=0;j<maxnum;j++) {
  611.             fprintf (fd,"D ");
  612.             for(i=0;i<pD->m_ninputs;i++) { 
  613.                 fprintf (fd,"\t");
  614.                 fprintf (fd,"%s",DRescaleFmt(pD,DGetInputVal(pD,j,i),'I',i));
  615.             }
  616.             fprintf (fd,"  ");
  617.             for(i=0;i<pD->m_noutputs;i++) {
  618.                 fprintf (fd,"\t");
  619.                 fprintf (fd,"%s",DRescaleFmt(pD,DGetOutputVal(pD,j,i),'O',i));
  620.             }
  621.             fprintf (fd,"\n");
  622.         }                
  623. //        if (m_numrows>10) fprintf (fd,"Only 10 out of %d shown\n",m_numrows);
  624.         for (j=0;j<pD->m_numtests;j++) {
  625.             fprintf (fd,"T ");
  626.             for(i=0;i<pD->m_ninputs;i++) {
  627.                 fprintf (fd,"\t");
  628.                 fprintf (fd,"%s",DRescaleFmt(pD,DGetInputTVal(pD,j,i),'I',i));
  629.             }
  630.             fprintf (fd,"  ");
  631.             for(i=0;i<pD->m_noutputs;i++) {
  632.                 fprintf (fd,"\t");
  633.                 fprintf (fd,"%s",DRescaleFmt(pD,DGetOutputTVal(pD,j,i),'O',i));
  634.             }
  635.             fprintf (fd,"\n");
  636.         }
  637.     }
  638.     if (nodata) fprintf (fd,"\nNo data loaded\n");
  639. }
  640.