home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e065 / 2.ddi / BALISTIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  12.4 KB  |  413 lines

  1. /* 09:46 04-Jul-88  (balistio.c)  Verion 2.00 */
  2.  
  3. /************************************************************************
  4.  * Copyright(C) 1988-1990 NeuralWare Inc
  5.  * Penn Center West, IV-227, Pittsburgh, PA 15276
  6.  *
  7.  * All rights reserved.  No part of this program may be reproduced,
  8.  * stored in a retrieval system, or transmitted, in any form or by any
  9.  * means, electronic, mechanical, photocopying, recording or otherwise
  10.  * without the prior written permission of the copyright owner,
  11.  * NeuralWare, Inc.
  12.  ************************************************************************
  13.  */
  14.  
  15. #include "userutl.h"
  16. #ifndef SUN
  17. #ifndef DLC
  18. #include <stdlib.h>
  19. #endif
  20. #endif
  21. #include <math.h>
  22.  
  23. #ifdef MAC
  24. #include  "macuio.redef"
  25. #endif
  26.  
  27. #undef  LOGGING
  28.  
  29. #define arraysize(array)  (sizeof(array) / sizeof(array[0]))
  30.  
  31. /************************************************************************
  32.  *                  *
  33.  *  Sample User I/O for the Balistics Problem     *
  34.  *                  *
  35.  ************************************************************************
  36.  */
  37.  
  38. FILE *fplog = {0};
  39.  
  40. /************************************************************************
  41.  *                  *
  42.  *  UsrIO - user I/O routine to handle requests from NWORKS   *
  43.  *                  *
  44.  ************************************************************************
  45.  
  46.     Output Layer:   Lc
  47.  
  48.  
  49.     Input Layer:    alpha, Vinitial, Height
  50.  
  51.     NOTE:  Must pre-scale things to the range 0->1.
  52.      Alpha: 0->90 -> 0->1
  53.      Vinitial:  0->100  -> 0->1
  54.      Height:  0->100  -> 0->1
  55.      Lc:    0->400  -> 0->1
  56.  */
  57.  
  58. #define TORAD(x)  ((x)*.017453293)  /* degrees to radians */
  59.  
  60. double impact( alpha, vi, h )   /* compute impact distance */
  61. double alpha;   /* firing angle */
  62. double vi;    /* firing velocity */
  63. double h;   /* height */
  64. {
  65.   double g; /* gravity */
  66.   double ta;  /* ?? */
  67.   double sina;  /* sin(alpha) */
  68.   double visina;  /* vi * sin(alpha) */
  69.   double li;  /* impact point */
  70.  
  71.   g = 32;         /* gravity */
  72.   sina  = sin(TORAD(alpha));
  73.   visina  = vi * sina;
  74.   ta  = (visina + sqrt( visina*visina + 2 * g * h ) ) / g;
  75.   li  = vi * cos(TORAD(alpha)) * ta;
  76.  
  77.   return( li );
  78. }
  79.  
  80.  
  81.  
  82. /* The following data structure defines the sample points selected for
  83.    training the network.  The columns are:
  84.  
  85.   Alpha - firing angle ( 0..90 )
  86.   V - initial velocity ( 0..100 )
  87.   H - height above impact point ( 0..100 )
  88.   Impact point - distance from cannon to impact point
  89. */
  90.  
  91. struct _td {
  92.   float td_alpha, td_vi, td_h, td_hit;
  93. };
  94. typedef struct _td TD;
  95. TD test_d[] = {
  96.  
  97. {    0.0,    0.0,    0.0,     0.0000 },
  98. {    0.0,    0.0,   20.0,     0.0000 },
  99. {    0.0,    0.0,   40.0,     0.0000 },
  100. {    0.0,    0.0,   60.0,     0.0000 },
  101. {    0.0,    0.0,   80.0,     0.0000 },
  102.  
  103. {    0.0,   20.0,    0.0,     0.0000 },
  104. {    0.0,   20.0,   20.0,    22.3607 },
  105. {    0.0,   20.0,   40.0,    31.6228 },
  106. {    0.0,   20.0,   60.0,    38.7298 },
  107. {    0.0,   20.0,   80.0,    44.7214 },
  108.  
  109. {    0.0,   40.0,    0.0,     0.0000 },
  110. {    0.0,   40.0,   20.0,    44.7214 },
  111. {    0.0,   40.0,   40.0,    63.2456 },
  112. {    0.0,   40.0,   60.0,    77.4597 },
  113. {    0.0,   40.0,   80.0,    89.4427 },
  114.  
  115. {    0.0,   60.0,    0.0,     0.0000 },
  116. {    0.0,   60.0,   20.0,    67.0820 },
  117. {    0.0,   60.0,   40.0,    94.8683 },
  118. {    0.0,   60.0,   60.0,   116.1895 },
  119. {    0.0,   60.0,   80.0,   134.1641 },
  120.  
  121. {    0.0,   80.0,    0.0,     0.0000 },
  122. {    0.0,   80.0,   20.0,    89.4427 },
  123. {    0.0,   80.0,   40.0,   126.4911 },
  124. {    0.0,   80.0,   60.0,   154.9193 },
  125. {    0.0,   80.0,   80.0,   178.8854 },
  126.  
  127. {    0.0,  100.0,    0.0,     0.0000 },
  128. {    0.0,  100.0,   20.0,   111.8034 },
  129. {    0.0,  100.0,   40.0,   158.1139 },
  130. {    0.0,  100.0,   60.0,   193.6492 },
  131. {    0.0,  100.0,   80.0,   223.6068 },
  132.  
  133. {   30.0,    0.0,    0.0,     0.0000 },
  134. {   30.0,    0.0,   20.0,     0.0000 },
  135. {   30.0,    0.0,   40.0,     0.0000 },
  136. {   30.0,    0.0,   60.0,     0.0000 },
  137. {   30.0,    0.0,   80.0,     0.0000 },
  138.  
  139. {   30.0,   20.0,    0.0,    10.8253 },
  140. {   30.0,   20.0,   20.0,    25.5198 },
  141. {   30.0,   20.0,   40.0,    33.3285 },
  142. {   30.0,   20.0,   60.0,    39.3876 },
  143. {   30.0,   20.0,   80.0,    44.5189 },
  144.  
  145. {   30.0,   40.0,    0.0,    43.3013 },
  146. {   30.0,   40.0,   20.0,    66.0212 },
  147. {   30.0,   40.0,   40.0,    80.5467 },
  148. {   30.0,   40.0,   60.0,    92.1400 },
  149. {   30.0,   40.0,   80.0,   102.0792 },
  150.  
  151. {   30.0,   60.0,    0.0,    97.4279 },
  152. {   30.0,   60.0,   20.0,   124.5298 },
  153. {   30.0,   60.0,   40.0,   144.2286 },
  154. {   30.0,   60.0,   60.0,   160.5086 },
  155. {   30.0,   60.0,   80.0,   174.7022 },
  156.  
  157. {   30.0,   80.0,    0.0,   173.2051 },
  158. {   30.0,   80.0,   20.0,   202.7920 },
  159. {   30.0,   80.0,   40.0,   226.2449 },
  160. {   30.0,   80.0,   60.0,   246.2897 },
  161. {   30.0,   80.0,   80.0,   264.0849 },
  162.  
  163. {   30.0,  100.0,    0.0,   270.6329 },
  164. {   30.0,  100.0,   20.0,   301.7062 },
  165. {   30.0,  100.0,   40.0,   327.8276 },
  166. {   30.0,  100.0,   60.0,   350.8056 },
  167. {   30.0,  100.0,   80.0,   371.5590 },
  168.  
  169. {   60.0,    0.0,    0.0,     0.0000 },
  170. {   60.0,    0.0,   20.0,     0.0000 },
  171. {   60.0,    0.0,   40.0,     0.0000 },
  172. {   60.0,    0.0,   60.0,     0.0000 },
  173. {   60.0,    0.0,   80.0,     0.0000 },
  174.  
  175. {   60.0,   20.0,    0.0,    10.8253 },
  176. {   60.0,   20.0,   20.0,    17.8343 },
  177. {   60.0,   20.0,   40.0,    22.1248 },
  178. {   60.0,   20.0,   60.0,    25.5198 },
  179. {   60.0,   20.0,   80.0,    28.4191 },
  180.  
  181. {   60.0,   40.0,    0.0,    43.3013 },
  182. {   60.0,   40.0,   20.0,    52.7754 },
  183. {   60.0,   40.0,   40.0,    59.9749 },
  184. {   60.0,   40.0,   60.0,    66.0212 },
  185. {   60.0,   40.0,   80.0,    71.3371 },
  186.  
  187. {   60.0,   60.0,    0.0,    97.4279 },
  188. {   60.0,   60.0,   20.0,   107.8582 },
  189. {   60.0,   60.0,   40.0,   116.7069 },
  190. {   60.0,   60.0,   60.0,   124.5298 },
  191. {   60.0,   60.0,   80.0,   131.6178 },
  192.  
  193. {   60.0,   80.0,    0.0,   173.2051 },
  194. {   60.0,   80.0,   20.0,   184.0705 },
  195. {   60.0,   80.0,   40.0,   193.8406 },
  196. {   60.0,   80.0,   60.0,   202.7920 },
  197. {   60.0,   80.0,   80.0,   211.1015 },
  198.  
  199. {   60.0,  100.0,    0.0,   270.6329 },
  200. {   60.0,  100.0,   20.0,   281.7253 },
  201. {   60.0,  100.0,   40.0,   292.0345 },
  202. {   60.0,  100.0,   60.0,   301.7062 },
  203. {   60.0,  100.0,   80.0,   310.8458 },
  204.  
  205. {   90.0,    0.0,    0.0,     0.0000 },
  206. {   90.0,    0.0,   20.0,     0.0000 },
  207. {   90.0,    0.0,   40.0,     0.0000 },
  208. {   90.0,    0.0,   60.0,     0.0000 },
  209. {   90.0,    0.0,   80.0,     0.0000 },
  210.  
  211. {   90.0,   20.0,    0.0,    -0.0000 },
  212. {   90.0,   20.0,   20.0,    -0.0000 },
  213. {   90.0,   20.0,   40.0,    -0.0000 },
  214. {   90.0,   20.0,   60.0,    -0.0000 },
  215. {   90.0,   20.0,   80.0,    -0.0000 },
  216.  
  217. {   90.0,   40.0,    0.0,    -0.0000 },
  218. {   90.0,   40.0,   20.0,    -0.0000 },
  219. {   90.0,   40.0,   40.0,    -0.0000 },
  220. {   90.0,   40.0,   60.0,    -0.0000 },
  221. {   90.0,   40.0,   80.0,    -0.0000 },
  222.  
  223. {   90.0,   60.0,    0.0,    -0.0000 },
  224. {   90.0,   60.0,   20.0,    -0.0000 },
  225. {   90.0,   60.0,   40.0,    -0.0000 },
  226. {   90.0,   60.0,   60.0,    -0.0000 },
  227. {   90.0,   60.0,   80.0,    -0.0000 },
  228.  
  229. {   90.0,   80.0,    0.0,    -0.0000 },
  230. {   90.0,   80.0,   20.0,    -0.0000 },
  231. {   90.0,   80.0,   40.0,    -0.0000 },
  232. {   90.0,   80.0,   60.0,    -0.0000 },
  233. {   90.0,   80.0,   80.0,    -0.0000 },
  234.  
  235. {   90.0,  100.0,    0.0,    -0.0000 },
  236. {   90.0,  100.0,   20.0,    -0.0000 },
  237. {   90.0,  100.0,   40.0,    -0.0000 },
  238. {   90.0,  100.0,   60.0,    -0.0000 },
  239. {   90.0,  100.0,   80.0,    -0.0000 }
  240. };
  241.  
  242. int SampX[arraysize(test_d)] = {0};   /* random sample index */
  243. int SX = {-1};        /* index into sample array */
  244.  
  245. int UsrIO()     /* handle NWORKS requests */
  246. {
  247.     char *sp;         /* string pointer */
  248.     int   wx;         /* work index */
  249.     char  buf[90];        /* work buffer */
  250.     static int inited = {0};      /* initialized */
  251.     static double alpha = {0.0};    /* angle */
  252.     static double vi  = {0.0};    /* velocity */
  253.     static double height= {0.0};    /* height */
  254.     static double hit = {0.0};    /* impact point */
  255.  
  256.     static double ainc  = {15.0};   /* alhpa increment */
  257.     static double viinc = {20.0};   /* velocity increment */
  258.     static double hinc  = {20.0};   /* height increment */
  259.  
  260.     static double t     = {0.0};    /* temp */
  261.     static double error = {0.0};    /* mean square error */
  262.     static int    round = {0};      /* just make a round */
  263.     static long   cycle = {0};      /* cycle number */
  264.     static int    pres  = {0};      /* presentation number */
  265.            int    r;        /* random number */
  266.  
  267.     IORTNCDE = 0;       /* good return for data */
  268.     switch( IOREQCDE ) {
  269.     case RQ_LEARNIN:        /* read training input */
  270.   /* IODATA points to an empty array of IOCOUNT elements.  The
  271.      values placed in this array by the user will become the
  272.      inputs to the network for training purposes.
  273.   */
  274.  
  275.   round = 0;
  276.   if ( inited == 0 ) {
  277.       cycle  = 1;
  278.       inited = 1;
  279.       pres   = arraysize(test_d);
  280.   }
  281.  
  282.   if ( --pres < 0 ) round = 1;
  283.  
  284.   /* generate a uniformly distributed array of sample data */
  285.   if ( SX < 0 || SX >= arraysize(test_d) ) {
  286.       for( SX = 0; SX < arraysize(test_d); SX++ ) {
  287.       RandAgain:
  288.     r = rand() % arraysize(test_d);
  289.     for( wx = 0; wx < SX; wx++ ) {
  290.         if ( SampX[wx] == r ) goto RandAgain;
  291.     }
  292.     SampX[SX] = r;
  293.       }
  294.       SX = 0;
  295.   }
  296.  
  297.   r = SampX[SX++];
  298.  
  299.   alpha  = test_d[r].td_alpha;
  300.   vi     = test_d[r].td_vi;
  301.   height = test_d[r].td_h;
  302.   hit    = test_d[r].td_hit;
  303.  
  304.   if ( IOCOUNT >= 3 ) {
  305.       IODATA[0] = alpha;
  306.       IODATA[1] = vi;
  307.       IODATA[2] = height;
  308.   }
  309.   break;
  310.  
  311.     case RQ_LEARNOUT:       /* read desired output */
  312.   /* IODATA points to an empty array of IOCOUNT values.  The
  313.      elements of the array will become the desired outputs for
  314.      training purposes.  These desired outputs correspond to
  315.      the most recent "RQ_LEARNIN" request.
  316.   */
  317.  
  318.   IODATA[0] = hit;
  319.   break;
  320.  
  321.     case RQ_LEARNRSLT:
  322.   t     = (hit - IODATA[0]);
  323.   error = error + t * t;
  324. #ifdef LOGGING
  325.   if ( fplog == (FILE *)0 )
  326.       fplog = fopen( "log", "a" );
  327.   if ( (cycle % 20) == 0 )
  328.     fprintf( fplog,
  329.      "cy=%3ld a=%5.1f vi=%5.1f h=%5.1f r=%7.2f cp=%7.2f er=%7.2f%s",
  330.       cycle, alpha, vi, height, IODATA[0], hit, error, NEW_LINE_STR );
  331. #endif
  332.   if ( round ) {
  333.       pres  = arraysize(test_d);
  334.       error = sqrt(error) / pres;
  335.  
  336.       sprintf( buf, "cycle = %ld, error = %.3f\n", cycle, error );
  337.       PutStr( buf );
  338.  
  339.       if ( error < 0.1 )  IORTNCDE = -1;    /* done */
  340.       else    IORTNCDE = 1;   /* update display */
  341.       error = 0.0;
  342.       round = 0;
  343.       cycle++;
  344.   }
  345.   break;
  346.  
  347.     case RQ_READ:       /* read test data */
  348.   /* IODATA points to an empty array of IOCOUNT values.  The
  349.      user must fill in these values.  The elements of the
  350.      array will become the "sum" of the inputs to the input
  351.      layer of processing elements.
  352.   */ 
  353.  
  354.   PutStr(
  355. "\nEnter Alpha (0-90), Vi (0-100), H (0-100) or E=end: " );
  356.   sp = GetStr();
  357.  
  358.   if ( *sp == 'e' || *sp == 'E' ) {
  359.       IORTNCDE = -1;      /* end of input */
  360.       break;
  361.   }
  362.  
  363. #ifdef THINK_C
  364.   sscanf( sp, "%Lf %Lf %Lf", &alpha, &vi, &height );
  365. #else
  366.   sscanf( sp, "%lf %lf %lf", &alpha, &vi, &height );
  367. #endif
  368.  
  369.   hit = impact( alpha, vi, height );
  370.   IODATA[0] = alpha;
  371.   IODATA[1] = vi;
  372.   IODATA[2] = height;
  373.   break;
  374.  
  375.     case RQ_RCLTST:   /* read desired output during recall test */
  376.   /* IODATA points to an empty array of IOCOUNT values.  The
  377.      elements of the array will become the desired outputs for
  378.      recall purposes.  This request is only made during a
  379.      Execute Network/Recall Test.
  380.   */
  381.  
  382.   IODATA[0] = hit;
  383.   break;
  384.  
  385.     case RQ_WRITE:        /* write out results */
  386.   /* IODATA points to an array of IOCOUNT "float" type values.
  387.      The values are the outputs of the top-most layer of the
  388.      network.
  389.   */
  390.  
  391.   sprintf( buf, "Network Hit = %.3lf, computed impact = %.3lf",
  392.     IODATA[0], hit );
  393.   PutStr( buf );
  394.   IORTNCDE = 1;       /* update display */
  395.   break;
  396.  
  397.     case RQ_TERM:       /* terminate interface */
  398.   /* close any files which may be open.  Deallocate any memory
  399.      which was allocated.  (This is VERY VERY important.  If
  400.      allocated memory is NOT released, dos memory will become
  401.      fragmented and it will become necessary to reboot.
  402.   */
  403.  
  404. #ifdef LOGGING
  405.   fclose( fplog );
  406. #endif
  407.   PutStr( "bye bye\n" );
  408.   break;
  409.     }
  410.  
  411.     return( 0 );
  412. }
  413.