home *** CD-ROM | disk | FTP | other *** search
/ CICA 1994 September / CICA_Shareware_for_Windows_Walnut_Creek_September_1994.iso / win3 / programr / atre27.exe / ATREE_27 / LFWIN / LF.C < prev    next >
C/C++ Source or Header  |  1992-08-01  |  24KB  |  952 lines

  1.  
  2. /*****************************************************************************
  3.  ****                                                                     ****
  4.  **** lf.c                                                                ****
  5.  ****                                                                     ****
  6.  **** atree release 2.7 for Windows                                       ****
  7.  **** Adaptive Logic Network (ALN) simulation program.                    ****
  8.  **** Copyright (C) A. Dwelly, R. Manderscheid, M. Thomas, W.W. Armstrong ****
  9.  ****               1991, 1992                                            ****
  10.  ****                                                                     ****
  11.  **** License:                                                            ****
  12.  **** A royalty-free license is granted for the use of this software for  ****
  13.  **** NON_COMMERCIAL PURPOSES ONLY. The software may be copied and/or     ****
  14.  **** modified provided this notice appears in its entirety and unchanged ****
  15.  **** in all derived source programs.  Persons modifying the code are     ****
  16.  **** requested to state the date, the changes made and who made them     ****
  17.  **** in the modification history.                                        ****
  18.  ****                                                                     ****
  19.  **** Patent License:                                                     ****
  20.  **** The use of a digital circuit which transmits a signal indicating    ****
  21.  **** heuristic responsibility is protected by U. S. Patent 3,934,231     ****
  22.  **** and others assigned to Dendronic Decisions Limited of Edmonton,     ****
  23.  **** W. W. Armstrong, President.  A royalty-free license is granted      ****
  24.  **** by the company to use this patent for NON_COMMERCIAL PURPOSES to    ****
  25.  **** adapt logic trees using this program and its modifications.         ****
  26.  ****                                                                     ****
  27.  **** Limited Warranty:                                                   ****
  28.  **** This software is provided "as is" without warranty of any kind,     ****
  29.  **** either expressed or implied, including, but not limited to, the     ****
  30.  **** implied warrantees of merchantability and fitness for a particular  ****
  31.  **** purpose.  The entire risk as to the quality and performance of the  ****
  32.  **** program is with the user.  Neither the authors, nor the             ****
  33.  **** University of Alberta, its officers, agents, servants or employees  ****
  34.  **** shall be liable or responsible in any way for any damage to         ****
  35.  **** property or direct personal or consequential injury of any nature   ****
  36.  **** whatsoever that may be suffered or sustained by any licensee, user  ****
  37.  **** or any other party as a consequence of the use or disposition of    ****
  38.  **** this software.                                                      ****
  39.  **** Modification history:                                               ****
  40.  ****                                                                     ****
  41.  **** 90.09.05 Initial implementation, A.Dwelly                           ****
  42.  **** 91.04.15 Port to PC and minor bug fixes, R. Manderscheid            ****
  43.  **** 91.05.20 Windows Port & Windows Extensions, M. Thomas               ****
  44.  **** 91.07.17 atree v2.0 for Windows, M. Thomas                          ****
  45.  **** 92.04.27 atree v2.5 for Windows, M. Thomas                          ****
  46.  **** 92.03.07 Release 2.6, Monroe Thomas                                 ****
  47.  **** 92.01.08 Release 2.7, Monroe Thomas                                 ****
  48.  ****                                                                     ****
  49.  *****************************************************************************/
  50.  
  51. #include <windows.h>
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include "atree.h"
  55. #include "lf.h"
  56.  
  57. #define VERBOSITY 0
  58.  
  59. extern int errno;
  60. extern char * sys_errlist[];
  61.  
  62. extern FILE *yyin;
  63. extern int line_no;
  64.  
  65. /* for use in winsynan.c in Windows version */
  66. float far * far *tmp_table;
  67.  
  68. BOOL lf_quit = FALSE;
  69.  
  70. prog_t prog;
  71. BOOL fold_flag; /* true if saving folded trees */
  72.             /* remaining flags true if corresponding statement
  73.                      has been specified. */
  74. BOOL test_size_flag;
  75. BOOL train_size_flag;
  76. BOOL largest_flag;
  77. BOOL smallest_flag;
  78. BOOL code_flag;
  79. BOOL quant_flag;
  80.  
  81. HWND hlfStatus;
  82.  
  83. #pragma argsused
  84. long FAR PASCAL lfStatusDlgProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
  85. {
  86.     if ((message == WM_COMMAND) && (wParam == IDCANCEL))
  87.     {
  88.         lf_quit = TRUE;
  89.         return(TRUE);
  90.     }
  91.     return(FALSE);
  92. }
  93.  
  94. void PASCAL
  95. prog_init(HANDLE hInstance, HWND hwnd)
  96. {
  97.     atree_init(hInstance, hwnd);
  98.  
  99.     train_size_flag = FALSE;
  100.     test_size_flag = FALSE;
  101.     largest_flag = FALSE;
  102.     smallest_flag = FALSE;
  103.     code_flag = FALSE;
  104.     quant_flag = FALSE;
  105.     fold_flag = FALSE;
  106.  
  107.     prog.forest_folded = FALSE;
  108.     prog.testset_sz = 0;
  109.     prog.trainset_sz = 0;
  110.     prog.tree_sz = 0;
  111.     prog.min_correct = 0;
  112.     prog.vote = 1;
  113.     prog.max_epochs = 0;
  114.     prog.test_table = NULL;
  115.     prog.train_table = NULL;
  116.     prog.code = NULL;
  117.     prog.walk_step = NULL;
  118.     prog.save_tree = NULL;
  119.     prog.load_tree = NULL;
  120.     prog.save_code = NULL;
  121.     prog.load_code = NULL;
  122.  
  123.     tmp_table = NULL;
  124. }
  125.  
  126. int PASCAL
  127. read_prog(fp)
  128.  
  129. FILE *fp;
  130.  
  131. {
  132.     yyin = fp;
  133.     line_no = 1;
  134.  
  135.     if(yyparse())       /* returns 1 if fatal error */
  136.         return(TRUE);
  137.     else
  138.         return(FALSE);
  139. }
  140.  
  141. BOOL set_encodings(HWND hwnd)
  142. {
  143.     char szBuffer[80];
  144.     int dim;
  145.     int i;
  146.  
  147.     if (prog.load_code == NULL && (!code_flag || !quant_flag))
  148.     {
  149.         wsprintf(szBuffer, "either coding+quantization or code load file must be specified.\n");
  150.         MessageBox(hwnd, szBuffer, "lf process_prog()", MB_OK | MB_ICONEXCLAMATION);
  151.         return(0);
  152.     }
  153.  
  154.     for (dim = 0; dim < prog.total_dimensions; dim++)
  155.     {
  156.         prog.code[dim].vector = NULL;
  157.     }
  158.  
  159.     if (prog.load_code)
  160.     {
  161.         FILE *fp;
  162.  
  163.         if ((fp = fopen(prog.load_code, "r")) == NULL)
  164.         {
  165.             wsprintf(szBuffer,"Can't open %s ", (LPSTR)prog.load_code);
  166.             MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  167.             return(0);
  168.         }
  169.         for (dim = 0; dim < prog.total_dimensions; dim++)
  170.         {
  171.  
  172.             if (atree_read_code((FILE far *)fp, &prog.code[dim]) == NULL)
  173.             {
  174.                 wsprintf(szBuffer, "too few codings in file '%s'\n",(LPSTR)prog.load_code);
  175.                 MessageBox(hwnd, szBuffer, "lf process_prog()", MB_OK | MB_ICONEXCLAMATION);
  176.                 return(0);
  177.             }
  178.         }
  179.         fclose(fp);
  180.     }
  181.     else
  182.     {
  183.         for (dim = 0; dim < prog.total_dimensions; dim++)
  184.         {
  185.             if (!largest_flag)
  186.             {
  187.                 prog.code[dim].high = prog.train_table[dim][0];
  188.  
  189.                 for (i = 1; i < prog.trainset_sz; i++)
  190.                 {
  191.                     if (prog.train_table[dim][i] > prog.code[dim].high)
  192.                     {
  193.                         prog.code[dim].high = prog.train_table[dim][i];
  194.                     }
  195.                 }
  196.  
  197.                 for (i = 0; i < prog.testset_sz; i++)
  198.                 {
  199.                     if (prog.test_table[dim][i] > prog.code[dim].high)
  200.                     {
  201.                         prog.code[dim].high = prog.test_table[dim][i];
  202.                     }
  203.                 }
  204.             }
  205.             if (!smallest_flag)
  206.             {
  207.                 prog.code[dim].low = prog.train_table[dim][0];
  208.  
  209.                 for (i = 1; i < prog.trainset_sz; i++)
  210.                 {
  211.                     if (prog.train_table[dim][i] < prog.code[dim].low)
  212.                     {
  213.                         prog.code[dim].low = prog.train_table[dim][i];
  214.                     }
  215.                 }
  216.  
  217.                 for (i = 0; i < prog.testset_sz; i++)
  218.                 {
  219.                     if (prog.test_table[dim][i] < prog.code[dim].low)
  220.                     {
  221.                         prog.code[dim].low = prog.test_table[dim][i];
  222.                     }
  223.                 }
  224.             }
  225.  
  226.             if (prog.code[dim].high <= prog.code[dim].low)
  227.             {
  228.                 wsprintf(szBuffer, "largest value must be greater than smallest value, column %d\n", dim + 1);
  229.                 MessageBox(hwnd, szBuffer, "lf set_encodings()", MB_OK | MB_ICONEXCLAMATION);
  230.                 return(0);
  231.             }
  232.  
  233.             /* finish constructing code for this dimension */
  234.  
  235.             if (atree_set_code(&prog.code[dim], prog.code[dim].low,
  236.                                                 prog.code[dim].high,
  237.                                                 prog.code[dim].vector_count,
  238.                                                 prog.code[dim].width,
  239.                                                 prog.walk_step[dim]))
  240.             {
  241.                 wsprintf(szBuffer,"random walk failed for dimension %d\n",dim + 1);
  242.                 MessageBox(hwnd, szBuffer, "lf set_encodings", MB_OK | MB_ICONEXCLAMATION);
  243.                 return(0);
  244.             }
  245.         } /* for (dim...) */
  246.     }
  247.     return(TRUE);
  248. }
  249.  
  250. BOOL PASCAL
  251. process_prog(HWND hwnd, HANDLE hInstance)
  252.  
  253. {
  254.     int dim;
  255.     int voter;
  256.     int i;
  257.     LPATREE tree;
  258.     LPBIT_VEC far *concat;
  259.     LPBIT_VEC domain_set;
  260.     LPBIT_VEC codomain_set;
  261.     FILE *save_tree_fp = NULL;
  262.     FILE *save_code_fp = NULL;
  263.     FILE *load_tree_fp = NULL;
  264.     char szBuffer[80];
  265.  
  266.     /*
  267.      * When this function is called, the program has been read in, and
  268.      * the relevant details have been stored in the global structure
  269.      * 'prog'. We have some semantic processing to do, then the trees
  270.      * can be trained as specified.
  271.      */
  272.  
  273.     if (prog.tree_sz == 0 && prog.load_tree == NULL)
  274.     {
  275.         wsprintf(szBuffer, "either tree size or tree load file must be specified\n");
  276.         MessageBox(hwnd, szBuffer, "lf process_prog()", MB_OK | MB_ICONEXCLAMATION);
  277.         return(0);
  278.     }
  279.  
  280.     if ((prog.load_tree != NULL && (prog.save_tree != NULL))
  281.     && (!strcmpi(prog.load_tree, prog.save_tree)))
  282.     {
  283.         wsprintf(szBuffer, "Save tree and load tree filenames must be different.\n");
  284.         MessageBox(hwnd, szBuffer, "lf process_prog()", MB_OK | MB_ICONEXCLAMATION);
  285.         return(0);
  286.     }
  287.  
  288.     if (prog.load_tree != NULL
  289.     && (load_tree_fp = fopen(prog.load_tree, "r")) == NULL)
  290.     {
  291.         wsprintf(szBuffer,"Can't open %s ", (LPSTR)prog.load_tree);
  292.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  293.         return(0);
  294.     }
  295.  
  296.     if (prog.save_tree != NULL
  297.     && (save_tree_fp = fopen(prog.save_tree, "w")) == NULL)
  298.     {
  299.         wsprintf(szBuffer,"Can't open %s ", (LPSTR)prog.save_tree);
  300.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  301.         return(0);
  302.     }
  303.  
  304.     if (save_tree_fp == NULL && (save_tree_fp = fopen("$$$lf$$$.tmp", "w")) == NULL)
  305.     {
  306.         wsprintf(szBuffer,"Can't open LF swap file $$$lf$$$.tmp");
  307.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  308.         return(0);
  309.     }
  310.  
  311.     if (prog.save_code != NULL
  312.     && (save_code_fp = fopen(prog.save_code, "w")) == NULL)
  313.     {
  314.         wsprintf(szBuffer,"Can't open %s ", (LPSTR)prog.save_code);
  315.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  316.         return(0);
  317.     }
  318.  
  319.     hlfStatus = CreateDialog(hInstance, "lfStatus", hwnd,
  320.                                  MakeProcInstance((FARPROC)lfStatusDlgProc, hInstance));
  321.  
  322.     SetDlgItemText(hlfStatus, IDD_TEXT, "Building training data...");
  323.     SetDlgItemText(hlfStatus, IDD_PERCENT, "0 %");
  324.     EnableWindow(GetDlgItem(hlfStatus, IDCANCEL), FALSE);
  325.  
  326.     if (!set_encodings(hwnd))
  327.     {
  328.         if (IsWindow(hlfStatus)) DestroyWindow(hlfStatus);
  329.         return(0);
  330.     }
  331.  
  332.     domain_set = (LPBIT_VEC) Malloc((unsigned) sizeof(bit_vec) *
  333.                                     prog.trainset_sz);
  334.     MEMCHECK(domain_set);
  335.     codomain_set = (LPBIT_VEC) Malloc((unsigned) sizeof(bit_vec) *
  336.                                       prog.trainset_sz);
  337.     MEMCHECK(codomain_set);
  338.  
  339.     prog.domain_width = 0;
  340.     prog.codomain_width = 0;
  341.     for (dim = 0; dim < prog.total_dimensions; dim++)
  342.     {
  343.         if (dim < prog.dimensions)
  344.         {
  345.             prog.domain_width += prog.code[dim].width;
  346.         }
  347.         else
  348.         {
  349.             prog.codomain_width += prog.code[dim].width;
  350.         }
  351.     }
  352.  
  353.     /*
  354.      * code[i] covers the dimension i.
  355.      * we now create the training set of bit vectors.
  356.      */
  357.  
  358.     concat = (LPBIT_VEC FAR *) Malloc((unsigned)(prog.total_dimensions) *
  359.                                   sizeof(LPBIT_VEC));
  360.     MEMCHECK(concat);
  361.  
  362.     for (i = 0; i < prog.trainset_sz; i++)
  363.     {
  364.         for (dim = 0; dim < prog.total_dimensions; dim++)
  365.         {
  366.             concat[dim] = prog.code[dim].vector
  367.                           + atree_encode(prog.train_table[dim][i],
  368.                                          &prog.code[dim]);
  369.         }
  370.         domain_set[i] = *(bv_concat(prog.dimensions, concat));
  371.         codomain_set[i] = *(bv_concat(prog.codimensions,
  372.                                       concat + prog.dimensions));
  373.  
  374.         sprintf(szBuffer, "%3.1f %%",((float)i / prog.trainset_sz) * 100);
  375.         SetDlgItemText(hlfStatus, IDD_PERCENT, (LPSTR)szBuffer);
  376.     }
  377.  
  378.     Free(concat);
  379.  
  380.     if (IsWindow(hlfStatus))    DestroyWindow(hlfStatus);
  381.  
  382.     /*
  383.      * Train the trees.
  384.      */
  385.  
  386.     if (prog.max_epochs > 0)
  387.     {
  388.         for (i = 0; i < prog.codomain_width; i++)
  389.         {
  390.             for (voter = 0; voter < prog.vote; voter++)
  391.             {
  392.                 if (lf_quit) return(0);
  393.                 if (load_tree_fp != NULL)
  394.                 {
  395.                     if ((tree = atree_read((FILE far *)load_tree_fp)) == NULL)
  396.                     {
  397.                         sprintf(szBuffer, "too few trees in file '%s'\n",(LPSTR)prog.load_tree);
  398.                         MessageBox(hwnd, szBuffer, "lf process_prog()", MB_OK | MB_ICONEXCLAMATION);
  399.                         return(0);
  400.                     }
  401.                 }
  402.                 else
  403.                 {
  404.                     tree = atree_create(prog.domain_width,prog.tree_sz);
  405.                 }
  406.  
  407.                 if (atree_train(tree, domain_set, codomain_set,
  408.                                    i, prog.trainset_sz, prog.min_correct,
  409.                                    prog.max_epochs, 1) == -1)
  410.                 {
  411.                     atree_free(tree);
  412.                     lf_quit = TRUE;
  413.                     if (load_tree_fp != NULL)
  414.                     {
  415.                         fclose(load_tree_fp);
  416.                     }
  417.  
  418.                     if (save_tree_fp != NULL)
  419.                     {
  420.                         fclose(save_tree_fp);
  421.                     }
  422.                     return(1);
  423.                 }
  424.  
  425.                 if (prog.save_tree)
  426.                 {
  427.                     if (fold_flag)
  428.                     {
  429.                         tree = atree_fold(tree);
  430.                     }
  431.                 }
  432.                 else
  433.                 {
  434.                     /* fold tree for swap file if not already done */
  435.                     tree = atree_fold(tree);
  436.                 }
  437.                 atree_write((FILE far *)save_tree_fp, tree);
  438.                 atree_free(tree);
  439.             }
  440.         }
  441.     }
  442.  
  443.     if (fold_flag || (!prog.save_tree))
  444.     {
  445.         prog.forest_folded = TRUE;
  446.     }
  447.  
  448.     if (load_tree_fp != NULL)
  449.     {
  450.         fclose(load_tree_fp);
  451.     }
  452.  
  453.     if (save_tree_fp != NULL)
  454.     {
  455.         fclose(save_tree_fp);
  456.     }
  457.  
  458.     /*
  459.      * Save codings
  460.      */
  461.  
  462.     if (save_code_fp != NULL)
  463.     {
  464.         int dim;
  465.  
  466.         for (dim = 0; dim < prog.total_dimensions; dim++)
  467.         {
  468.             atree_write_code((FILE far *)save_code_fp, &prog.code[dim]);
  469.         }
  470.         fclose(save_code_fp);
  471.     }
  472.  
  473.     for (i = 0; i < prog.trainset_sz; i++)
  474.     {
  475.         Free(domain_set[i].bv);
  476.         Free(codomain_set[i].bv);
  477.     }
  478.     Free(domain_set);
  479.     Free(codomain_set);
  480.     return(1);
  481. }
  482.  
  483. BOOL PASCAL
  484. test_prog(HWND hwnd, LPSTR szOutFile, HANDLE hInstance)
  485.  
  486. {
  487.     char szBuffer[80];
  488.     int i, j;
  489.     int dim;
  490.     int col;
  491.     int nv;
  492.     LPATREE FAR *trees;
  493.     LPFAST_TREE *ftrees;
  494.     LPBIT_VEC FAR *test_vec;
  495.     LPBIT_VEC FAR * FAR *result;
  496.     LPBIT_VEC FAR *concat;
  497.     FILE *load_tree_fp = NULL;
  498.     FILE* out_fp;
  499.     int far * far * histogram;
  500.     int total_samples = 0;
  501.     float total = 0;
  502.  
  503.     if(prog.trainset_sz == 0)
  504.     {
  505.         // get trees from load file if no training set
  506.         if ((load_tree_fp = fopen(prog.load_tree, "r")) == NULL)
  507.         {
  508.             wsprintf(szBuffer,"Can't open %s ", (LPSTR)prog.load_tree);
  509.             MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  510.             return(FALSE);
  511.         }
  512.     }
  513.  
  514.     // else get trees from save file if specified
  515.     if (load_tree_fp == NULL && prog.save_tree != NULL
  516.     && (load_tree_fp = fopen(prog.save_tree, "r")) == NULL)
  517.     {
  518.         wsprintf(szBuffer,"Can't open %s ", (LPSTR)prog.save_tree);
  519.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  520.         return(FALSE);
  521.     }
  522.  
  523.     // else get trees from swap file
  524.     if (load_tree_fp == NULL
  525.     &&(load_tree_fp = fopen("$$$lf$$$.tmp", "r")) == NULL)
  526.     {
  527.         wsprintf(szBuffer,"Can't open LF swap file $$$lf$$$.tmp");
  528.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  529.         return(FALSE);
  530.     }
  531.  
  532.     if ((out_fp = fopen(szOutFile, "w")) == NULL)
  533.     {
  534.        wsprintf(szBuffer,"Can't open %s ", (LPSTR)szOutFile);
  535.        MessageBox(hwnd, szBuffer, "LF File Error", MB_OK);
  536.        return(FALSE);
  537.     }
  538.  
  539.     hlfStatus = CreateDialog(hInstance, "lfStatus", hwnd,
  540.                              MakeProcInstance((FARPROC)lfStatusDlgProc, hInstance));
  541.     SetDlgItemText(hlfStatus, IDD_TEXT, "Evaluating test data...");
  542.     SetDlgItemText(hlfStatus, IDD_PERCENT, "0 %");
  543.  
  544.     if (prog.trainset_sz == 0 && !set_encodings(hwnd))
  545.     {
  546.         if (IsWindow(hlfStatus)) DestroyWindow(hlfStatus);
  547.         return(FALSE);
  548.     }
  549.  
  550.     trees = (LPATREE FAR *) Malloc((unsigned)(prog.vote) * sizeof(LPATREE));
  551.     MEMCHECK(trees);
  552.  
  553.     ftrees = (LPFAST_TREE FAR *) Malloc((unsigned)(prog.vote) * sizeof(LPFAST_TREE));
  554.     MEMCHECK(ftrees);
  555.  
  556.     /*
  557.      * We need a result vector for each codomain dimension
  558.      * because bv_diff expects vectors of equal length.
  559.      */
  560.     result = (LPBIT_VEC FAR * FAR *)
  561.              Malloc((unsigned)(prog.codimensions) * sizeof(LPBIT_VEC FAR *));
  562.     MEMCHECK(result);
  563.     for (dim = prog.dimensions; dim < prog.total_dimensions; dim++)
  564.     {
  565.         result[dim - prog.dimensions] = (LPBIT_VEC FAR *) Malloc((unsigned)(prog.testset_sz) *
  566.                                          sizeof(LPBIT_VEC));
  567.         MEMCHECK(result);
  568.         for (i = 0; i < prog.testset_sz; i++)
  569.         {
  570.             result[dim - prog.dimensions][i] = bv_create(prog.code[dim].width);
  571.         }
  572.     }
  573.  
  574.     /*
  575.      * Create test vectors and print out test info.
  576.      * Remember to bv_free test_vec after each iteration.
  577.      */
  578.  
  579.     concat = (LPBIT_VEC FAR *) Malloc((unsigned)(prog.dimensions) *
  580.                                 sizeof(LPBIT_VEC));
  581.     MEMCHECK(concat);
  582.  
  583.     test_vec = (LPBIT_VEC FAR *) Malloc((unsigned)(prog.testset_sz) *
  584.                                          sizeof(LPBIT_VEC));
  585.     MEMCHECK(test_vec);
  586.  
  587.     for (i = 0; i < prog.testset_sz; i++)
  588.     {
  589.         for (dim = 0; dim < prog.total_dimensions; dim++)
  590.         {
  591.             nv = atree_encode(prog.test_table[dim][i], &prog.code[dim]);
  592.             if (dim < prog.dimensions)
  593.             {
  594.                 concat[dim] = prog.code[dim].vector + nv;
  595.             }
  596.         }
  597.         test_vec[i] = bv_concat(prog.dimensions, concat);
  598.     }
  599.     Free(concat);
  600.  
  601.  
  602.     for (dim = prog.dimensions; dim < prog.total_dimensions; dim++)
  603.     {
  604.         total_samples += prog.code[dim].width * prog.testset_sz;
  605.     }
  606.  
  607.     /*
  608.      * for each codomain dimension ...
  609.      */
  610.     for (dim = prog.dimensions; dim < prog.total_dimensions; dim++)
  611.     {
  612.         int bit_no;
  613.  
  614.         for (bit_no = 0; bit_no < prog.code[dim].width; bit_no++)
  615.         {
  616.             for (i = 0; i < prog.vote; i++)
  617.             {
  618.                 Windows_Interrupt(200);
  619.  
  620.                 if ((trees[i] = atree_read((FILE far *)load_tree_fp)) == NULL)
  621.                 {
  622.                     sprintf(szBuffer, "too few trees in file '%s'\n",(LPSTR)prog.load_tree);
  623.                     MessageBox(hwnd, szBuffer, "lf process_prog()", MB_OK | MB_ICONEXCLAMATION);
  624.                     if (IsWindow(hlfStatus)) DestroyWindow(hlfStatus);
  625.                     return(FALSE);
  626.                 }
  627.                 if (!prog.forest_folded)
  628.                 {
  629.                     trees[i] = atree_fold(trees[i]);
  630.                 }
  631.                 ftrees[i] = atree_compress(trees[i]);
  632.                 atree_free(trees[i]);
  633.             }
  634.  
  635.             /*
  636.              * for each element of the training set ...
  637.              */
  638.  
  639.             for (i = 0; i < prog.testset_sz; i++)
  640.             {
  641.                 int weight = 0;
  642.                 int voter;
  643.  
  644.                 total ++;
  645.  
  646.                 sprintf(szBuffer, "%3.1f %%", (total / total_samples) * 100.0);
  647.                 SetDlgItemText(hlfStatus, IDD_PERCENT, (LPSTR)szBuffer);
  648.  
  649.                 /*
  650.                  * Calculate result for this dimension.
  651.                  */
  652.  
  653.                 for (voter = 0; voter < prog.vote; voter++)
  654.                 {
  655.                     if (atree_fast_eval(ftrees[voter], test_vec[i]))
  656.                     {
  657.                         weight++;
  658.                     }
  659.                 }
  660.                 bv_set(bit_no, result[dim - prog.dimensions][i], weight > prog.vote / 2);
  661.             }
  662.         } /* for (bit_no...) */
  663.  
  664.         for (i = 0; i < prog.vote; i++)
  665.         {
  666.             Free(ftrees[i]);
  667.         }
  668.  
  669.         if (lf_quit)
  670.         {
  671.             break;
  672.         }
  673.  
  674.     } /* for (dim...) */
  675.  
  676.     /* set up histogram buckets for each codim */
  677.  
  678. #define NUM_BUCKETS 10
  679.  
  680.     histogram = (int far * far *) Malloc((unsigned)(prog.codimensions) * sizeof(int far *));
  681.     MEMCHECK(histogram);
  682.  
  683.     for (dim = 0; dim < prog.codimensions; dim++)
  684.     {
  685.         histogram[dim] = (int far *) Malloc((unsigned)NUM_BUCKETS * sizeof(int));
  686.         MEMCHECK(histogram[dim]);
  687.         for (i = 0; i < NUM_BUCKETS; i++)
  688.         {
  689.             histogram[dim][i] = 0;
  690.         }
  691.     }
  692.  
  693.     /* perform output */
  694.  
  695.     if (!lf_quit)
  696.     {
  697.         fprintf(out_fp,"%d\n", prog.codimensions);
  698.         for (i = 0; i < prog.testset_sz; i++)
  699.         {
  700.             for (dim = 0; dim < prog.total_dimensions; dim++)
  701.             {
  702.                 int closest;
  703.  
  704.                 nv = atree_encode(prog.test_table[dim][i], &prog.code[dim]);
  705.                 fprintf(out_fp, "%s%f %d", dim ? "\t" : "", prog.test_table[dim][i], nv);
  706.  
  707.                 if (dim >= prog.dimensions)
  708.                 {
  709.                     closest = atree_decode(result[dim - prog.dimensions][i], &prog.code[dim]);
  710.  
  711.                     fprintf(out_fp, "\t%f %d",
  712.                         prog.code[dim].low + prog.code[dim].step * closest, closest);
  713.  
  714.                     closest = abs(closest - nv);
  715.                     if (closest < (NUM_BUCKETS - 1))
  716.                     {
  717.                         histogram[dim - prog.dimensions][closest] += 1;
  718.                     }
  719.                     else
  720.                     {
  721.                         histogram[dim - prog.dimensions][NUM_BUCKETS - 1] += 1;
  722.                     }
  723.                 }
  724.             }
  725.             fprintf(out_fp,"\n");
  726.         } /* for i... */
  727.  
  728.         fprintf(out_fp,"\nERROR HISTOGRAM\n");
  729.  
  730.         for (i = 0; i < NUM_BUCKETS; i++)
  731.         {
  732.             if (i < (NUM_BUCKETS - 1))
  733.                 fprintf(out_fp, "Out by %d  levels", i);
  734.             else
  735.                 fprintf(out_fp, "Out by %d+ levels", i);
  736.             for (dim = 0; dim < prog.codimensions; dim++)
  737.             {
  738.                 fprintf(out_fp, "\t%d", histogram[dim][i]);
  739.             }
  740.             fprintf(out_fp,"\n");
  741.         }
  742.     }
  743.  
  744.     /* clean up */
  745.  
  746.     Free(trees);
  747.     Free(ftrees);
  748.  
  749.     for (dim = 0; dim < prog.codimensions; dim++)
  750.     {
  751.         for (i = 0; i < prog.testset_sz; i++)
  752.         {
  753.             bv_free(result[dim][i]);
  754.         }
  755.         Free(histogram[dim]);
  756.         Free(result[dim]);
  757.     }
  758.     Free(histogram);
  759.     Free(result);
  760.  
  761.     for (i = 0; i < prog.testset_sz; i++)
  762.     {
  763.         bv_free(test_vec[i]);
  764.     }
  765.     Free(test_vec);
  766.  
  767.     fclose(out_fp);       /* close output file */
  768.     fclose(load_tree_fp);
  769.     if (IsWindow(hlfStatus)) DestroyWindow(hlfStatus);
  770.     return(TRUE);
  771. }
  772.  
  773. BOOL PASCAL
  774. lf_main(HWND hwnd, LPSTR szInFile, LPSTR szOutFile, HANDLE hInstance)
  775.  
  776. {
  777.     FILE *fp;
  778.     char szFileName[80];
  779.     int i, j;
  780.     char szBuffer[80];
  781.     HCURSOR hCursor;
  782.  
  783.     hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  784.     ShowCursor(TRUE);
  785.  
  786.     /* Initialise the default values for the program */
  787.  
  788.     prog_init(hInstance, hwnd);
  789.  
  790.     if (szInFile == NULL)
  791.     {
  792.         MessageBox(hwnd, "No Input File Specified", "LF File Error", MB_OK);
  793.         return(FALSE);
  794.     }
  795.     if (szOutFile == NULL)
  796.     {
  797.         MessageBox(hwnd, "No Output File Specified", "LF File Error", MB_OK);
  798.         return(0);
  799.     }
  800.  
  801.     /* Read the input file */
  802.  
  803.     lstrcpy((LPSTR)szFileName, szInFile);   /* fopen needs near pointer */
  804.  
  805.     if ((fp = fopen(szFileName,"r")) == NULL)
  806.     {
  807.         char szBuffer[80];
  808.         wsprintf(szBuffer,"Can't open %s ", (LPSTR)szInFile);
  809.         MessageBox(NULL, szBuffer, "LF File Error", MB_OK);
  810.         ShowCursor(FALSE);
  811.         SetCursor(hCursor);
  812.         atree_quit();
  813.         return (FALSE);
  814.     }
  815.     else
  816.     {
  817.         int tmp;
  818.         tmp = read_prog(fp);
  819.         (void) fclose(fp);
  820.         if (tmp || prog.error)
  821.         {
  822.             ShowCursor(FALSE);
  823.             SetCursor(hCursor);
  824.             atree_quit();
  825.             prog.error = FALSE;
  826.             lf_quit = FALSE;
  827.             return(FALSE);
  828.         }
  829.     }
  830.  
  831.     line_no = 1;
  832.  
  833.     ShowCursor(FALSE);
  834.     SetCursor(hCursor);
  835.  
  836.     if (!prog.error && (prog.testset_sz == 0) && (prog.trainset_sz == 0))
  837.     {
  838.         wsprintf(szBuffer, "Cannot have both test and training sets empty.\n");
  839.         MessageBox(hwnd, szBuffer, "lf_main()", MB_OK | MB_ICONEXCLAMATION);
  840.         prog.error = TRUE;
  841.     }
  842.  
  843.     if (!prog.error && (prog.trainset_sz == 0) && (prog.load_tree == NULL))
  844.     {
  845.         wsprintf(szBuffer,
  846.         "Cannot have empty training set without specifying tree load file.\n");
  847.         MessageBox(hwnd, szBuffer, "lf_main()", MB_OK | MB_ICONEXCLAMATION);
  848.         prog.error = TRUE;
  849.     }
  850.  
  851.     /* Train the trees as specified if there were no syntax errors */
  852.  
  853.     if (!prog.error)
  854.     {
  855.         if (prog.trainset_sz != 0)
  856.         {
  857.             if(!process_prog(hwnd, hInstance))
  858.             {
  859.                 prog.error = TRUE;
  860.             }
  861.         }
  862.     }
  863.  
  864.     /* Execute the trees as specified */
  865.  
  866.     if (lf_quit)
  867.     {
  868.         prog.error = TRUE;
  869.     }
  870.  
  871.     if (!prog.error)
  872.     {
  873.         if (prog.testset_sz != 0)
  874.         {
  875.             if(!test_prog(hwnd, szOutFile, hInstance))
  876.             {
  877.                 prog.error = TRUE;
  878.             }
  879.         }
  880.     }
  881.  
  882.     if (lf_quit)
  883.     {
  884.         prog.error = TRUE;
  885.     }
  886.  
  887.     if (!prog.error)
  888.     {
  889.         if(prog.testset_sz != 0)
  890.         {
  891.             sprintf(szBuffer,"notepad.exe %s", szOutFile);
  892.             WinExec(szBuffer, SW_SHOWNORMAL);
  893.         }
  894.     }
  895.  
  896.     /* Finish */
  897.  
  898.     prog.error = FALSE;
  899.     lf_quit = FALSE;
  900.     atree_quit();
  901.  
  902.     if (prog.save_tree == NULL)
  903.     {
  904.         remove("$$$lf$$$.tmp");
  905.     }
  906.  
  907.     for (i = 0; i < prog.total_dimensions; i++)
  908.     {
  909.         for (j = 0; j < prog.code[i].vector_count; j++)
  910.         {
  911.             if (prog.code[i].vector != NULL)
  912.             {
  913.                 Free(prog.code[i].vector[j].bv);
  914.             }
  915.         }
  916.         if (prog.code[i].vector != NULL)
  917.         {
  918.             Free(prog.code[i].vector);
  919.         }
  920.         if (prog.trainset_sz && prog.train_table[i] != NULL)
  921.         {
  922.             Free(prog.train_table[i]);
  923.         }
  924.         if (prog.testset_sz && prog.test_table[i] != NULL)
  925.         {
  926.             Free(prog.test_table[i]);
  927.         }
  928.     }
  929.     if(prog.train_table != NULL)
  930.     {
  931.         Free(prog.train_table);
  932.     }
  933.     if(prog.test_table != NULL)
  934.     {
  935.         Free(prog.test_table);
  936.     }
  937.     if(tmp_table != NULL)
  938.     {
  939.         Free(tmp_table);
  940.     }
  941.     if(prog.walk_step != NULL)
  942.     {
  943.         Free(prog.walk_step);
  944.     }
  945.     if(prog.code != NULL)
  946.     {
  947.         Free(prog.code);
  948.     }
  949.  
  950.     return(TRUE);
  951. }
  952.