home *** CD-ROM | disk | FTP | other *** search
- /* 09:46 04-Jul-88 (balistio.c) Verion 2.00 */
-
- /************************************************************************
- * Copyright(C) 1988-1990 NeuralWare Inc
- * Penn Center West, IV-227, Pittsburgh, PA 15276
- *
- * All rights reserved. No part of this program may be reproduced,
- * stored in a retrieval system, or transmitted, in any form or by any
- * means, electronic, mechanical, photocopying, recording or otherwise
- * without the prior written permission of the copyright owner,
- * NeuralWare, Inc.
- ************************************************************************
- */
-
- #include "userutl.h"
- #ifndef SUN
- #ifndef DLC
- #include <stdlib.h>
- #endif
- #endif
- #include <math.h>
-
- #ifdef MAC
- #include "macuio.redef"
- #endif
-
- #undef LOGGING
-
- #define arraysize(array) (sizeof(array) / sizeof(array[0]))
-
- /************************************************************************
- * *
- * Sample User I/O for the Balistics Problem *
- * *
- ************************************************************************
- */
-
- FILE *fplog = {0};
-
- /************************************************************************
- * *
- * UsrIO - user I/O routine to handle requests from NWORKS *
- * *
- ************************************************************************
-
- Output Layer: Lc
-
-
- Input Layer: alpha, Vinitial, Height
-
- NOTE: Must pre-scale things to the range 0->1.
- Alpha: 0->90 -> 0->1
- Vinitial: 0->100 -> 0->1
- Height: 0->100 -> 0->1
- Lc: 0->400 -> 0->1
- */
-
- #define TORAD(x) ((x)*.017453293) /* degrees to radians */
-
- double impact( alpha, vi, h ) /* compute impact distance */
- double alpha; /* firing angle */
- double vi; /* firing velocity */
- double h; /* height */
- {
- double g; /* gravity */
- double ta; /* ?? */
- double sina; /* sin(alpha) */
- double visina; /* vi * sin(alpha) */
- double li; /* impact point */
-
- g = 32; /* gravity */
- sina = sin(TORAD(alpha));
- visina = vi * sina;
- ta = (visina + sqrt( visina*visina + 2 * g * h ) ) / g;
- li = vi * cos(TORAD(alpha)) * ta;
-
- return( li );
- }
-
-
-
- /* The following data structure defines the sample points selected for
- training the network. The columns are:
-
- Alpha - firing angle ( 0..90 )
- V - initial velocity ( 0..100 )
- H - height above impact point ( 0..100 )
- Impact point - distance from cannon to impact point
- */
-
- struct _td {
- float td_alpha, td_vi, td_h, td_hit;
- };
- typedef struct _td TD;
- TD test_d[] = {
-
- { 0.0, 0.0, 0.0, 0.0000 },
- { 0.0, 0.0, 20.0, 0.0000 },
- { 0.0, 0.0, 40.0, 0.0000 },
- { 0.0, 0.0, 60.0, 0.0000 },
- { 0.0, 0.0, 80.0, 0.0000 },
-
- { 0.0, 20.0, 0.0, 0.0000 },
- { 0.0, 20.0, 20.0, 22.3607 },
- { 0.0, 20.0, 40.0, 31.6228 },
- { 0.0, 20.0, 60.0, 38.7298 },
- { 0.0, 20.0, 80.0, 44.7214 },
-
- { 0.0, 40.0, 0.0, 0.0000 },
- { 0.0, 40.0, 20.0, 44.7214 },
- { 0.0, 40.0, 40.0, 63.2456 },
- { 0.0, 40.0, 60.0, 77.4597 },
- { 0.0, 40.0, 80.0, 89.4427 },
-
- { 0.0, 60.0, 0.0, 0.0000 },
- { 0.0, 60.0, 20.0, 67.0820 },
- { 0.0, 60.0, 40.0, 94.8683 },
- { 0.0, 60.0, 60.0, 116.1895 },
- { 0.0, 60.0, 80.0, 134.1641 },
-
- { 0.0, 80.0, 0.0, 0.0000 },
- { 0.0, 80.0, 20.0, 89.4427 },
- { 0.0, 80.0, 40.0, 126.4911 },
- { 0.0, 80.0, 60.0, 154.9193 },
- { 0.0, 80.0, 80.0, 178.8854 },
-
- { 0.0, 100.0, 0.0, 0.0000 },
- { 0.0, 100.0, 20.0, 111.8034 },
- { 0.0, 100.0, 40.0, 158.1139 },
- { 0.0, 100.0, 60.0, 193.6492 },
- { 0.0, 100.0, 80.0, 223.6068 },
-
- { 30.0, 0.0, 0.0, 0.0000 },
- { 30.0, 0.0, 20.0, 0.0000 },
- { 30.0, 0.0, 40.0, 0.0000 },
- { 30.0, 0.0, 60.0, 0.0000 },
- { 30.0, 0.0, 80.0, 0.0000 },
-
- { 30.0, 20.0, 0.0, 10.8253 },
- { 30.0, 20.0, 20.0, 25.5198 },
- { 30.0, 20.0, 40.0, 33.3285 },
- { 30.0, 20.0, 60.0, 39.3876 },
- { 30.0, 20.0, 80.0, 44.5189 },
-
- { 30.0, 40.0, 0.0, 43.3013 },
- { 30.0, 40.0, 20.0, 66.0212 },
- { 30.0, 40.0, 40.0, 80.5467 },
- { 30.0, 40.0, 60.0, 92.1400 },
- { 30.0, 40.0, 80.0, 102.0792 },
-
- { 30.0, 60.0, 0.0, 97.4279 },
- { 30.0, 60.0, 20.0, 124.5298 },
- { 30.0, 60.0, 40.0, 144.2286 },
- { 30.0, 60.0, 60.0, 160.5086 },
- { 30.0, 60.0, 80.0, 174.7022 },
-
- { 30.0, 80.0, 0.0, 173.2051 },
- { 30.0, 80.0, 20.0, 202.7920 },
- { 30.0, 80.0, 40.0, 226.2449 },
- { 30.0, 80.0, 60.0, 246.2897 },
- { 30.0, 80.0, 80.0, 264.0849 },
-
- { 30.0, 100.0, 0.0, 270.6329 },
- { 30.0, 100.0, 20.0, 301.7062 },
- { 30.0, 100.0, 40.0, 327.8276 },
- { 30.0, 100.0, 60.0, 350.8056 },
- { 30.0, 100.0, 80.0, 371.5590 },
-
- { 60.0, 0.0, 0.0, 0.0000 },
- { 60.0, 0.0, 20.0, 0.0000 },
- { 60.0, 0.0, 40.0, 0.0000 },
- { 60.0, 0.0, 60.0, 0.0000 },
- { 60.0, 0.0, 80.0, 0.0000 },
-
- { 60.0, 20.0, 0.0, 10.8253 },
- { 60.0, 20.0, 20.0, 17.8343 },
- { 60.0, 20.0, 40.0, 22.1248 },
- { 60.0, 20.0, 60.0, 25.5198 },
- { 60.0, 20.0, 80.0, 28.4191 },
-
- { 60.0, 40.0, 0.0, 43.3013 },
- { 60.0, 40.0, 20.0, 52.7754 },
- { 60.0, 40.0, 40.0, 59.9749 },
- { 60.0, 40.0, 60.0, 66.0212 },
- { 60.0, 40.0, 80.0, 71.3371 },
-
- { 60.0, 60.0, 0.0, 97.4279 },
- { 60.0, 60.0, 20.0, 107.8582 },
- { 60.0, 60.0, 40.0, 116.7069 },
- { 60.0, 60.0, 60.0, 124.5298 },
- { 60.0, 60.0, 80.0, 131.6178 },
-
- { 60.0, 80.0, 0.0, 173.2051 },
- { 60.0, 80.0, 20.0, 184.0705 },
- { 60.0, 80.0, 40.0, 193.8406 },
- { 60.0, 80.0, 60.0, 202.7920 },
- { 60.0, 80.0, 80.0, 211.1015 },
-
- { 60.0, 100.0, 0.0, 270.6329 },
- { 60.0, 100.0, 20.0, 281.7253 },
- { 60.0, 100.0, 40.0, 292.0345 },
- { 60.0, 100.0, 60.0, 301.7062 },
- { 60.0, 100.0, 80.0, 310.8458 },
-
- { 90.0, 0.0, 0.0, 0.0000 },
- { 90.0, 0.0, 20.0, 0.0000 },
- { 90.0, 0.0, 40.0, 0.0000 },
- { 90.0, 0.0, 60.0, 0.0000 },
- { 90.0, 0.0, 80.0, 0.0000 },
-
- { 90.0, 20.0, 0.0, -0.0000 },
- { 90.0, 20.0, 20.0, -0.0000 },
- { 90.0, 20.0, 40.0, -0.0000 },
- { 90.0, 20.0, 60.0, -0.0000 },
- { 90.0, 20.0, 80.0, -0.0000 },
-
- { 90.0, 40.0, 0.0, -0.0000 },
- { 90.0, 40.0, 20.0, -0.0000 },
- { 90.0, 40.0, 40.0, -0.0000 },
- { 90.0, 40.0, 60.0, -0.0000 },
- { 90.0, 40.0, 80.0, -0.0000 },
-
- { 90.0, 60.0, 0.0, -0.0000 },
- { 90.0, 60.0, 20.0, -0.0000 },
- { 90.0, 60.0, 40.0, -0.0000 },
- { 90.0, 60.0, 60.0, -0.0000 },
- { 90.0, 60.0, 80.0, -0.0000 },
-
- { 90.0, 80.0, 0.0, -0.0000 },
- { 90.0, 80.0, 20.0, -0.0000 },
- { 90.0, 80.0, 40.0, -0.0000 },
- { 90.0, 80.0, 60.0, -0.0000 },
- { 90.0, 80.0, 80.0, -0.0000 },
-
- { 90.0, 100.0, 0.0, -0.0000 },
- { 90.0, 100.0, 20.0, -0.0000 },
- { 90.0, 100.0, 40.0, -0.0000 },
- { 90.0, 100.0, 60.0, -0.0000 },
- { 90.0, 100.0, 80.0, -0.0000 }
- };
-
- int SampX[arraysize(test_d)] = {0}; /* random sample index */
- int SX = {-1}; /* index into sample array */
-
- int UsrIO() /* handle NWORKS requests */
- {
- char *sp; /* string pointer */
- int wx; /* work index */
- char buf[90]; /* work buffer */
- static int inited = {0}; /* initialized */
- static double alpha = {0.0}; /* angle */
- static double vi = {0.0}; /* velocity */
- static double height= {0.0}; /* height */
- static double hit = {0.0}; /* impact point */
-
- static double ainc = {15.0}; /* alhpa increment */
- static double viinc = {20.0}; /* velocity increment */
- static double hinc = {20.0}; /* height increment */
-
- static double t = {0.0}; /* temp */
- static double error = {0.0}; /* mean square error */
- static int round = {0}; /* just make a round */
- static long cycle = {0}; /* cycle number */
- static int pres = {0}; /* presentation number */
- int r; /* random number */
-
- IORTNCDE = 0; /* good return for data */
- switch( IOREQCDE ) {
- case RQ_LEARNIN: /* read training input */
- /* IODATA points to an empty array of IOCOUNT elements. The
- values placed in this array by the user will become the
- inputs to the network for training purposes.
- */
-
- round = 0;
- if ( inited == 0 ) {
- cycle = 1;
- inited = 1;
- pres = arraysize(test_d);
- }
-
- if ( --pres < 0 ) round = 1;
-
- /* generate a uniformly distributed array of sample data */
- if ( SX < 0 || SX >= arraysize(test_d) ) {
- for( SX = 0; SX < arraysize(test_d); SX++ ) {
- RandAgain:
- r = rand() % arraysize(test_d);
- for( wx = 0; wx < SX; wx++ ) {
- if ( SampX[wx] == r ) goto RandAgain;
- }
- SampX[SX] = r;
- }
- SX = 0;
- }
-
- r = SampX[SX++];
-
- alpha = test_d[r].td_alpha;
- vi = test_d[r].td_vi;
- height = test_d[r].td_h;
- hit = test_d[r].td_hit;
-
- if ( IOCOUNT >= 3 ) {
- IODATA[0] = alpha;
- IODATA[1] = vi;
- IODATA[2] = height;
- }
- break;
-
- case RQ_LEARNOUT: /* read desired output */
- /* IODATA points to an empty array of IOCOUNT values. The
- elements of the array will become the desired outputs for
- training purposes. These desired outputs correspond to
- the most recent "RQ_LEARNIN" request.
- */
-
- IODATA[0] = hit;
- break;
-
- case RQ_LEARNRSLT:
- t = (hit - IODATA[0]);
- error = error + t * t;
- #ifdef LOGGING
- if ( fplog == (FILE *)0 )
- fplog = fopen( "log", "a" );
- if ( (cycle % 20) == 0 )
- fprintf( fplog,
- "cy=%3ld a=%5.1f vi=%5.1f h=%5.1f r=%7.2f cp=%7.2f er=%7.2f%s",
- cycle, alpha, vi, height, IODATA[0], hit, error, NEW_LINE_STR );
- #endif
- if ( round ) {
- pres = arraysize(test_d);
- error = sqrt(error) / pres;
-
- sprintf( buf, "cycle = %ld, error = %.3f\n", cycle, error );
- PutStr( buf );
-
- if ( error < 0.1 ) IORTNCDE = -1; /* done */
- else IORTNCDE = 1; /* update display */
- error = 0.0;
- round = 0;
- cycle++;
- }
- break;
-
- case RQ_READ: /* read test data */
- /* IODATA points to an empty array of IOCOUNT values. The
- user must fill in these values. The elements of the
- array will become the "sum" of the inputs to the input
- layer of processing elements.
- */
-
- PutStr(
- "\nEnter Alpha (0-90), Vi (0-100), H (0-100) or E=end: " );
- sp = GetStr();
-
- if ( *sp == 'e' || *sp == 'E' ) {
- IORTNCDE = -1; /* end of input */
- break;
- }
-
- #ifdef THINK_C
- sscanf( sp, "%Lf %Lf %Lf", &alpha, &vi, &height );
- #else
- sscanf( sp, "%lf %lf %lf", &alpha, &vi, &height );
- #endif
-
- hit = impact( alpha, vi, height );
- IODATA[0] = alpha;
- IODATA[1] = vi;
- IODATA[2] = height;
- break;
-
- case RQ_RCLTST: /* read desired output during recall test */
- /* IODATA points to an empty array of IOCOUNT values. The
- elements of the array will become the desired outputs for
- recall purposes. This request is only made during a
- Execute Network/Recall Test.
- */
-
- IODATA[0] = hit;
- break;
-
- case RQ_WRITE: /* write out results */
- /* IODATA points to an array of IOCOUNT "float" type values.
- The values are the outputs of the top-most layer of the
- network.
- */
-
- sprintf( buf, "Network Hit = %.3lf, computed impact = %.3lf",
- IODATA[0], hit );
- PutStr( buf );
- IORTNCDE = 1; /* update display */
- break;
-
- case RQ_TERM: /* terminate interface */
- /* close any files which may be open. Deallocate any memory
- which was allocated. (This is VERY VERY important. If
- allocated memory is NOT released, dos memory will become
- fragmented and it will become necessary to reboot.
- */
-
- #ifdef LOGGING
- fclose( fplog );
- #endif
- PutStr( "bye bye\n" );
- break;
- }
-
- return( 0 );
- }
-