home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume29 / persim / part01 < prev    next >
Encoding:
Text File  |  1992-04-05  |  51.9 KB  |  1,735 lines

  1. Newsgroups: comp.sources.misc
  2. From: stein.wbst129@xerox.com (Adam Stein)
  3. Subject:  v29i054:  persim - Single-Layer Perceptron Simulator, Part01/03
  4. Message-ID: <csm-v29i054=persim.204901@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: e53a6e63eaa1f62270d48c2478f1c261
  6. Date: Sun, 5 Apr 1992 02:50:16 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: stein.wbst129@xerox.com (Adam Stein)
  10. Posting-number: Volume 29, Issue 54
  11. Archive-name: persim/part01
  12. Environment: BSD
  13.  
  14. Persim is a single-layer perceptron simulator that I had to write for a
  15. neural networks class.  Included are 2 examples to show that it works (and to
  16. show how to use it).
  17.  
  18. I hope it can be of some use.
  19.  
  20.         Adam Stein
  21.         stein.wbst129@xerox.com
  22.  
  23. ---- Cut Here and feed the following to sh ----
  24. #! /bin/sh
  25. # This is a shell archive.  Remove anything before this line, then feed it
  26. # into a shell via "sh file" or similar.  To overwrite existing files,
  27. # type "sh file -c".
  28. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  29. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  30. # Contents:  README example1 example1/output4 example2 is.c persim.1
  31. #   persim.h read.c run.c set.c show.c write.c
  32. # Wrapped by kent@sparky on Sat Apr  4 20:29:30 1992
  33. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  34. echo If this archive is complete, you will see the following message:
  35. echo '          "shar: End of archive 1 (of 3)."'
  36. if test -f 'README' -a "${1}" != "-c" ; then 
  37.   echo shar: Will not clobber existing file \"'README'\"
  38. else
  39.   echo shar: Extracting \"'README'\" \(1555 characters\)
  40.   sed "s/^X//" >'README' <<'END_OF_FILE'
  41. XThis is the README file for persim.
  42. X
  43. XAuthor:
  44. X
  45. X  Adam Stein (stein.wbst129@xerox.com)
  46. X
  47. XCopyright:
  48. X
  49. X  Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.
  50. X
  51. X  Permission to use,  copy,  modify  and  distribute  without
  52. X  charge this software, documentation, images, etc. is grant-
  53. X  ed, provided that this copyright and the author's  name  is
  54. X  retained.
  55. X
  56. X  A fee may be charged for this program ONLY to recover costs
  57. X  for distribution (i.e. media costs).  No profit can be made
  58. X  on this program.
  59. X
  60. X  The author assumes no responsibility for disasters (natural
  61. X  or otherwise) as a consequence of use of this software.
  62. X
  63. XDescription:
  64. X
  65. X  This program will simulate a single-layer perceptron.  This
  66. X  includes training as well as testing.  The convergence
  67. X  procedure used for training was developed by R. Rosenblatt.
  68. X
  69. X  See the man page for more details.
  70. X
  71. XInstallation:
  72. X
  73. X  This program has only been compiled and tested on BSD or BSD/SYS5
  74. X  mixed systems.  I have no idea what would have to be changed for
  75. X  a SYS5 only system (probably only index to strchr and that sort of
  76. X  stuff).  To compile use:
  77. X
  78. X        make
  79. X
  80. X  and to install the program and man page use
  81. X
  82. X        make install
  83. X
  84. XBugs/Additions:
  85. X
  86. X  While I don't plan on supporting this, I would appreciate
  87. X  knowing about any bug fixes or any enhancements made.
  88. X  I would like to keep a centralized version with the
  89. X  upgrades so that there aren't 50 million versions posted
  90. X  to the net.
  91. X
  92. X  I hope this program is of use to you, either in it's capacity or as simple
  93. X  example in single-layer perceptrons.
  94. X
  95. END_OF_FILE
  96.   if test 1555 -ne `wc -c <'README'`; then
  97.     echo shar: \"'README'\" unpacked with wrong size!
  98.   fi
  99.   # end of 'README'
  100. fi
  101. if test ! -d 'example1' ; then
  102.     echo shar: Creating directory \"'example1'\"
  103.     mkdir 'example1'
  104. fi
  105. if test -f 'example1/output4' -a "${1}" != "-c" ; then 
  106.   echo shar: Will not clobber existing file \"'example1/output4'\"
  107. else
  108.   echo shar: Extracting \"'example1/output4'\" \(5140 characters\)
  109.   sed "s/^X//" >'example1/output4' <<'END_OF_FILE'
  110. Xpersim> inodes=3
  111. Xpersim> onodes=1
  112. Xpersim> alpha=0.01
  113. Xpersim> node function step
  114. Xpersim> load input "input4.asc",asc
  115. Xpersim> load desired "desired4.asc",asc
  116. Xpersim> load weights "weights.asc",asc
  117. Xpersim> run verbose
  118. XEpoch #1:
  119. X  Actual Output Node #1 = 1.000000
  120. X
  121. X  [New] From #1, To #1, Weight = 0.376465
  122. X  [New] From #2, To #1, Weight = 0.812299
  123. X  [New] From #3, To #1, Weight = 0.352806
  124. X
  125. XEpoch #2:
  126. X  Actual Output Node #1 = 1.000000
  127. X
  128. X  [New] From #1, To #1, Weight = 0.356465
  129. X  [New] From #2, To #1, Weight = 0.784112
  130. X  [New] From #3, To #1, Weight = 0.352275
  131. X
  132. XEpoch #3:
  133. X  Actual Output Node #1 = 1.000000
  134. X
  135. X  [New] From #1, To #1, Weight = 0.336465
  136. X  [New] From #2, To #1, Weight = 0.755926
  137. X  [New] From #3, To #1, Weight = 0.351745
  138. X
  139. XEpoch #4:
  140. X  Actual Output Node #1 = 1.000000
  141. X
  142. X  [New] From #1, To #1, Weight = 0.316465
  143. X  [New] From #2, To #1, Weight = 0.727739
  144. X  [New] From #3, To #1, Weight = 0.351215
  145. X
  146. XEpoch #5:
  147. X  Actual Output Node #1 = 1.000000
  148. X
  149. X  [New] From #1, To #1, Weight = 0.296465
  150. X  [New] From #2, To #1, Weight = 0.699553
  151. X  [New] From #3, To #1, Weight = 0.350684
  152. X
  153. XEpoch #6:
  154. X  Actual Output Node #1 = 1.000000
  155. X
  156. X  [New] From #1, To #1, Weight = 0.276465
  157. X  [New] From #2, To #1, Weight = 0.671366
  158. X  [New] From #3, To #1, Weight = 0.350154
  159. X
  160. XEpoch #7:
  161. X  Actual Output Node #1 = 1.000000
  162. X
  163. X  [New] From #1, To #1, Weight = 0.256465
  164. X  [New] From #2, To #1, Weight = 0.643180
  165. X  [New] From #3, To #1, Weight = 0.349624
  166. X
  167. XEpoch #8:
  168. X  Actual Output Node #1 = 1.000000
  169. X
  170. X  [New] From #1, To #1, Weight = 0.236465
  171. X  [New] From #2, To #1, Weight = 0.614993
  172. X  [New] From #3, To #1, Weight = 0.349093
  173. X
  174. XEpoch #9:
  175. X  Actual Output Node #1 = 1.000000
  176. X
  177. X  [New] From #1, To #1, Weight = 0.216465
  178. X  [New] From #2, To #1, Weight = 0.586807
  179. X  [New] From #3, To #1, Weight = 0.348563
  180. X
  181. XEpoch #10:
  182. X  Actual Output Node #1 = 1.000000
  183. X
  184. X  [New] From #1, To #1, Weight = 0.196465
  185. X  [New] From #2, To #1, Weight = 0.558620
  186. X  [New] From #3, To #1, Weight = 0.348033
  187. X
  188. XEpoch #11:
  189. X  Actual Output Node #1 = 1.000000
  190. X
  191. X  [New] From #1, To #1, Weight = 0.176465
  192. X  [New] From #2, To #1, Weight = 0.530434
  193. X  [New] From #3, To #1, Weight = 0.347502
  194. X
  195. XEpoch #12:
  196. X  Actual Output Node #1 = 1.000000
  197. X
  198. X  [New] From #1, To #1, Weight = 0.156465
  199. X  [New] From #2, To #1, Weight = 0.502247
  200. X  [New] From #3, To #1, Weight = 0.346972
  201. X
  202. XEpoch #13:
  203. X  Actual Output Node #1 = 1.000000
  204. X
  205. X  [New] From #1, To #1, Weight = 0.136465
  206. X  [New] From #2, To #1, Weight = 0.474061
  207. X  [New] From #3, To #1, Weight = 0.346442
  208. X
  209. XEpoch #14:
  210. X  Actual Output Node #1 = 1.000000
  211. X
  212. X  [New] From #1, To #1, Weight = 0.116465
  213. X  [New] From #2, To #1, Weight = 0.445874
  214. X  [New] From #3, To #1, Weight = 0.345912
  215. X
  216. XEpoch #15:
  217. X  Actual Output Node #1 = 1.000000
  218. X
  219. X  [New] From #1, To #1, Weight = 0.096465
  220. X  [New] From #2, To #1, Weight = 0.417688
  221. X  [New] From #3, To #1, Weight = 0.345381
  222. X
  223. XEpoch #16:
  224. X  Actual Output Node #1 = 1.000000
  225. X
  226. X  [New] From #1, To #1, Weight = 0.076465
  227. X  [New] From #2, To #1, Weight = 0.389501
  228. X  [New] From #3, To #1, Weight = 0.344851
  229. X
  230. XEpoch #17:
  231. X  Actual Output Node #1 = 1.000000
  232. X
  233. X  [New] From #1, To #1, Weight = 0.056465
  234. X  [New] From #2, To #1, Weight = 0.361315
  235. X  [New] From #3, To #1, Weight = 0.344321
  236. X
  237. XEpoch #18:
  238. X  Actual Output Node #1 = 1.000000
  239. X
  240. X  [New] From #1, To #1, Weight = 0.036465
  241. X  [New] From #2, To #1, Weight = 0.333128
  242. X  [New] From #3, To #1, Weight = 0.343790
  243. X
  244. XEpoch #19:
  245. X  Actual Output Node #1 = 1.000000
  246. X
  247. X  [New] From #1, To #1, Weight = 0.016465
  248. X  [New] From #2, To #1, Weight = 0.304942
  249. X  [New] From #3, To #1, Weight = 0.343260
  250. X
  251. XEpoch #20:
  252. X  Actual Output Node #1 = 1.000000
  253. X
  254. X  [New] From #1, To #1, Weight = -0.003535
  255. X  [New] From #2, To #1, Weight = 0.276755
  256. X  [New] From #3, To #1, Weight = 0.342730
  257. X
  258. XEpoch #21:
  259. X  Actual Output Node #1 = 1.000000
  260. X
  261. X  [New] From #1, To #1, Weight = -0.023535
  262. X  [New] From #2, To #1, Weight = 0.248569
  263. X  [New] From #3, To #1, Weight = 0.342199
  264. X
  265. XEpoch #22:
  266. X  Actual Output Node #1 = 1.000000
  267. X
  268. X  [New] From #1, To #1, Weight = -0.043535
  269. X  [New] From #2, To #1, Weight = 0.220382
  270. X  [New] From #3, To #1, Weight = 0.341669
  271. X
  272. XEpoch #23:
  273. X  Actual Output Node #1 = 1.000000
  274. X
  275. X  [New] From #1, To #1, Weight = -0.063535
  276. X  [New] From #2, To #1, Weight = 0.192196
  277. X  [New] From #3, To #1, Weight = 0.341139
  278. X
  279. XEpoch #24:
  280. X  Actual Output Node #1 = 1.000000
  281. X
  282. X  [New] From #1, To #1, Weight = -0.083535
  283. X  [New] From #2, To #1, Weight = 0.164009
  284. X  [New] From #3, To #1, Weight = 0.340608
  285. X
  286. XEpoch #25:
  287. X  Actual Output Node #1 = 1.000000
  288. X
  289. X  [New] From #1, To #1, Weight = -0.103535
  290. X  [New] From #2, To #1, Weight = 0.135823
  291. X  [New] From #3, To #1, Weight = 0.340078
  292. X
  293. XEpoch #26:
  294. X  Actual Output Node #1 = 1.000000
  295. X
  296. X  [New] From #1, To #1, Weight = -0.123535
  297. X  [New] From #2, To #1, Weight = 0.107637
  298. X  [New] From #3, To #1, Weight = 0.339548
  299. X
  300. XEpoch #27:
  301. X  Actual Output Node #1 = 1.000000
  302. X
  303. X  [New] From #1, To #1, Weight = -0.143535
  304. X  [New] From #2, To #1, Weight = 0.079450
  305. X  [New] From #3, To #1, Weight = 0.339017
  306. X
  307. XEpoch #28:
  308. X  Actual Output Node #1 = -1.000000
  309. X
  310. X  [New] From #1, To #1, Weight = -0.143535
  311. X  [New] From #2, To #1, Weight = 0.079450
  312. X  [New] From #3, To #1, Weight = 0.339017
  313. X
  314. Xpersim> save weights "weights.asc",asc
  315. Xpersim> exit
  316. END_OF_FILE
  317.   if test 5140 -ne `wc -c <'example1/output4'`; then
  318.     echo shar: \"'example1/output4'\" unpacked with wrong size!
  319.   fi
  320.   # end of 'example1/output4'
  321. fi
  322. if test ! -d 'example2' ; then
  323.     echo shar: Creating directory \"'example2'\"
  324.     mkdir 'example2'
  325. fi
  326. if test -f 'is.c' -a "${1}" != "-c" ; then 
  327.   echo shar: Will not clobber existing file \"'is.c'\"
  328. else
  329.   echo shar: Extracting \"'is.c'\" \(4473 characters\)
  330.   sed "s/^X//" >'is.c' <<'END_OF_FILE'
  331. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  332. X
  333. X  Permission to use,  copy,  modify  and  distribute  without
  334. X  charge this software, documentation, images, etc. is grant-
  335. X  ed, provided that this copyright and the author's  name  is  
  336. X  retained.   
  337. X  
  338. X  A fee may be charged for this program ONLY to recover costs   
  339. X  for distribution (i.e. media costs).  No profit can be made            
  340. X  on this program.   
  341. X   
  342. X  The author assumes no responsibility for disasters (natural   
  343. X  or otherwise) as a consequence of use of this software.      
  344. X   
  345. X  Adam Stein (stein.wbst129@xerox.com)         
  346. X*/ 
  347. X
  348. X#include "persim.h"
  349. X#include "commands.h"
  350. X#include "grammar.h"
  351. X
  352. X/*This routine will determine if a string of characters is a keyword.
  353. X
  354. X  Inputs:  numargs   - (return value)
  355. X       string    - string of characters to identify as a keyword or not
  356. X  Outputs: numargs   - number of arguments this keyword takes
  357. X  Locals:  loop      - loop through list of keywords
  358. X       pointer   - pointer to each keyword in list to compare
  359. X  Globals: cmd       - name of keyword
  360. X       AMBIGUOUS - not enough of a keyword was given to distiguish it
  361. X       NUM_CMDS  - total number of commands available
  362. X       UNKNOWN   - string is not a keyword
  363. X*/
  364. Xiskeyword(string,numargs)
  365. Xregister int *numargs;
  366. Xregister char *string;
  367. X{
  368. X    register int loop;
  369. X    register char *pointer;
  370. X    char *strstr();
  371. X
  372. X    /*Look for a match*/
  373. X    for(loop = 0;loop < NUM_CMDS;++loop)
  374. X      if((pointer = strstr(cmd[loop].name,string)) == cmd[loop].name)
  375. X        break;
  376. X
  377. X    /*If didn't find a match, string is unknown*/
  378. X    if(loop == NUM_CMDS) loop = UNKNOWN;
  379. X    else {
  380. X           /*Find out if the 'match' matched more than 1 item (ambiguous)*/
  381. X           if((loop == (NUM_CMDS - 1)) ||
  382. X          (strstr(cmd[loop + 1].name,string) != cmd[loop + 1].name))
  383. X             *numargs = cmd[loop].numargs;
  384. X           else loop = AMBIGUOUS;
  385. X         }
  386. X
  387. X    return(loop);
  388. X}
  389. X
  390. X/*This routine will check to see if a string of characters is a qualifier.
  391. X
  392. X  Inputs:  type           - (return value)
  393. X       string         - string of characters to identify as a keyword or not
  394. X  Outputs: type           - type of qualifier (used in grammar.y)
  395. X  Locals:  loop           - loop through list of keywords
  396. X       pointer        - pointer to each keyword in list to compare
  397. X  Globals: AMBIGUOUS      - not enough of a qualifier was given to distiguish it
  398. X       ASCII      - qualifier relates to an ascii filetype
  399. X       BINARY      - qualifier relates to a binary filetype
  400. X       DATA         - data attribute (used in grammar.y)
  401. X       DESIRED      - qualifier relates to desired output values
  402. X       FILETYPE         - filetype attribute (used in grammar.y)
  403. X       FUNC_ATTR      - function attribute (used in grammar.y)
  404. X       FUNCTION      - qualifier relates to a node's function
  405. X       INPUT      - qualifier relates to input values
  406. X       NOTFILE      - loading values is not coming from a file (grammar.y)
  407. X       NUM_QUALIFIERS - total number of qualifiers
  408. X       OUTPUT      - qualifier relates to output values
  409. X       SYS_VARS       - qualifier relates to system variables
  410. X       RANDOM         - qualifier relates to using random values
  411. X       STDIN          - qualifier relates to loading values from keyboard
  412. X       THRESHOLD      - qualifier relates to threshold value
  413. X       THRESHOLD_ATTR - threshold attribute (used in grammar.y)
  414. X       WEIGHTS      - qualifier relates to weights
  415. X       UNKNOWN        - string is not a qualifier
  416. X       VERBOSE      - qualifier relates to verbosity of a command
  417. X       VERBOSE_ATTR   - verbose attribute (used in grammar.y)
  418. X*/
  419. Xisqualifier(string,type)
  420. Xregister int *type;
  421. Xregister char *string;
  422. X{
  423. X    register int loop;
  424. X    register char *pointer;
  425. X    char *strstr();
  426. X
  427. X    /*Look for a match*/
  428. X    for(loop = 0;loop < NUM_QUALIFIERS;++loop)
  429. X      if((pointer = strstr(qual[loop],string)) == qual[loop])
  430. X        break;
  431. X
  432. X    /*If didn't find a match, string is unknown*/
  433. X    if(loop == NUM_QUALIFIERS) loop = UNKNOWN;
  434. X    else if((loop != (NUM_QUALIFIERS - 1)) &&
  435. X        (strstr(qual[loop + 1],string) == qual[loop + 1]))
  436. X           loop = AMBIGUOUS;
  437. X         else loop += 50;
  438. X
  439. X    /*Find out which part of the grammar this qualifier belongs to*/
  440. X    switch(loop) {
  441. X      case ASCII:
  442. X      case BINARY:
  443. X            *type = FILETYPE;
  444. X            break;
  445. X      case DESIRED:
  446. X      case INPUT:
  447. X      case OUTPUT:
  448. X      case SYS_VARS:
  449. X      case WEIGHTS:
  450. X            *type = DATA;
  451. X            break;
  452. X      case RANDOM:
  453. X      case STDIN:
  454. X            *type = NOTFILE;
  455. X            break;
  456. X      case FUNCTION:
  457. X            *type = FUNC_ATTR;
  458. X            break;
  459. X      case THRESHOLD:
  460. X            *type = THRESHOLD_ATTR;
  461. X            break;
  462. X      case VERBOSE:
  463. X            *type = VERBOSE_ATTR;
  464. X            break;
  465. X    }
  466. X
  467. X    return(loop);
  468. X}
  469. X
  470. END_OF_FILE
  471.   if test 4473 -ne `wc -c <'is.c'`; then
  472.     echo shar: \"'is.c'\" unpacked with wrong size!
  473.   fi
  474.   # end of 'is.c'
  475. fi
  476. if test -f 'persim.1' -a "${1}" != "-c" ; then 
  477.   echo shar: Will not clobber existing file \"'persim.1'\"
  478. else
  479.   echo shar: Extracting \"'persim.1'\" \(6994 characters\)
  480.   sed "s/^X//" >'persim.1' <<'END_OF_FILE'
  481. X.ll 6.5i
  482. X.TH PERSIM 1 "16-Feb-92"
  483. X.SH NAME
  484. Xpersim - simple single layer perceptron simulator
  485. X.SH SYNOPSIS
  486. Xpersim [file]
  487. X.SH DESCRIPTION
  488. XPersim is a simple single layer perceptron simulator.  Simulation includes
  489. Xthe running of a perceptron as well as training one.  The
  490. Xconvergence procedure used for the training mode was developed by R. Rosenblatt
  491. X(see CONVERGENCE PROCEDURE below).
  492. X
  493. XThe optional filename argument (if given) is the name of a file containing
  494. X\f2persim\f1 commands.  If no arguement is given, \f2persim\f1 will run
  495. Xinteractively.
  496. X
  497. XTo terminate weight values coming from the keyboard, answer any of the
  498. Xquestions with just a carriage return.
  499. X
  500. XDuring 'run' mode, there are two special control chraracters, ^C and ^Z.
  501. XDuring a simulator, hitting ^C will quit the simulation and return to the
  502. X'persim' prompt.  ^Z is only used if the 'run' command isn't used verbosely.
  503. XIf run isn't used verbosely, ^Z will print out a snapshot of the simulation.
  504. XThis inclues the epoch number, the actual output value(s) and the weight
  505. Xvalue(s).
  506. X.SH COMMANDS
  507. XCommands may be abbreviated.  Just enough of a command to make it unique is
  508. Xneeded.
  509. X
  510. XSystem variables (mentioned in the commands below) are alpha, number of
  511. Xinput nodes, number of output nodes, and training mode (either on or off).
  512. X
  513. X.IP "? [command]"
  514. XThis is a synonym for the help command and can be used in place of 'help'.
  515. X.IP "alpha = #"
  516. XSet alpha equal to #.  # can be a number between 0.0 and 1.0 (inclusive).
  517. XDefault is 0.1.
  518. X.IP exit
  519. XExit the program.
  520. X.IP "help [command]"
  521. XDisplay information about the command specified.  If no command is specified,
  522. Xa list of all legal commands is given.
  523. X.IP "inodes = #"
  524. XSet the number of input nodes equal to #.  # can be 1 or greater.
  525. X.TP
  526. Xload <var> "filename"[, type]
  527. X.TP
  528. Xload <var> stdin
  529. X.IP "load <var> random"
  530. XLoad values of a variable (denoted by <var>).  Legal values for <var> are:
  531. X
  532. X.nf
  533. X.ta 5 15
  534. X    desired    (desired output)
  535. X    input    (input data)
  536. X    state    (system variables)
  537. X    weights    (weight data).
  538. X    
  539. X.fi
  540. XThe first form loads data from a filename (given by 'filename').  'Type' (if
  541. Xgiven) can be 'ascii' for ASCII files or 'binary' for binary files.  The
  542. Xsecond form uses the keyword 'stdin' to denote data coming from standard
  543. Xinput.  This second from will allow the user to input all of the data for
  544. X<var> directly from the keyboard.  The third form will load the variable
  545. Xwith random values between 0.0 and 1.0, inclusive.  This is only valid for
  546. Xthe weights variable.
  547. X.IP "node[#] attr value"
  548. XSet output node attributes.  Attributes (attr) can be set for just one node or
  549. Xfor all nodes.  To set an attribute for a particular node, use 'node#', where #
  550. Xis the number of the output node to set.  To set all output nodes, use 'node'
  551. Xwith no number.  'Attr' can be either 'function', to set a node's function,
  552. Xor 'threshold', to set a node's threshold.  'Value' is a floating point
  553. Xnumber if setting a threshold.  Legal values for 'value' is setting a
  554. Xfunction are 'step', for the step function, and 'arctan', for the
  555. Xarctangent function.
  556. X.IP "onodes = #"
  557. XSet the number of output nodes equal to #.  # can be 1 or greater.
  558. X.IP "range <obj> min max"
  559. XSet a range for an object.  The only value <obj> can be right now is 'step' for
  560. Xthe step function.  'Min' is the mininum and 'max' is the maximum range to
  561. Xset.  The default range for the step function is (-1.0,1.0).
  562. X.IP "run [verbose]"
  563. XRun the simulator.  If training mode is on, this command will train the
  564. Xperceptron.  If training mode is off, this will run input data through the
  565. Xperceptron.  If 'verbose' is given and the training mode is on, intermediate
  566. Xoutput values and weights will be displayed as the simulator goes through the
  567. Xepochs.
  568. X.TP
  569. Xsave <var> "filename"[, type]
  570. XSave variables to a file.  Legal values for <var> are:
  571. X
  572. X.nf
  573. X.ta 5 15
  574. X    desired    (desired output values)
  575. X    input    (input values)
  576. X    output    (output values)
  577. X    state    (system variables)
  578. X    weights    (weight values).
  579. X    
  580. X.fi
  581. X\'Filename\' is the name of the file to save to.  'Type' (if
  582. Xgiven) is the type of format to save to.  'Type' can be 'ascii' or 'binary'.
  583. X.IP "show <var>"
  584. XShow the value(s) of a variable.  Legal values for <var> are:
  585. X
  586. X.nf
  587. X.ta 5 15
  588. X    alpha    (the value of alpha)
  589. X    desired    (desired output values)
  590. X    inodes    (the number of input nodes)
  591. X    input    (input values),
  592. X    node[#]    (node information for all nodes or a particular
  593. X         node, as indicated by #),
  594. X    onodes    (the number of output nodes)
  595. X    output    (output values)
  596. X    range    (ranges)
  597. X    state    (system variables)
  598. X    training    (the state of the training mode)
  599. X    weights    (weight values).
  600. X.fi
  601. X.IP training
  602. XToggle training mode on and off.  Default value is on.
  603. X.IP version
  604. XDisplay current version and compile date.
  605. X.SH CONVERGENCE PROCEDURE
  606. XThe following steps are taken to train the perceptron.  This is taken from
  607. X"An Introduction to Computing with Neural Nets" by Richard P. Lippmann
  608. X.IP "Step 1.    Initialize Weights"
  609. XSet Wi(0) (0 <= i <= N - 1) to small random values if the weights don't
  610. Xalready have a value.  Here Wi(t) is the weight from input i at time t.
  611. X.IP "Step 2.    Present New Input and Desired Output"
  612. XPresent new continuous valued input X0,X1,...,Xn-1 along with the desired output
  613. Xd(t).
  614. X.IP "Step 3.    Calculate Actual Output"
  615. Xy(t) = fn(SUM Wi(t)Xi(t) - theta), where SUM is the mathematical summation
  616. Xsymbol and theta is the output node threshold.
  617. X.IP "Step 4.    Adapt Weights"
  618. XWi(t + 1) = Wi(t) + alpha[d(t) - y(t)]Xi(t), 0 <= i <= N - 1
  619. X
  620. X.nf
  621. X         _
  622. X        /  +1 if input from class A
  623. Xd(t) = -
  624. X        \\_ -1 if input from class B
  625. X.fi
  626. X
  627. XIn these equations, alpha is a positive gain fraction less than 1 and d(t) is
  628. Xthe desired correct output for the current input.  Note that weights are
  629. Xunchanged if the correct decision is made by the net.
  630. X.IP "Step 5.    Repeat by Going to Step 2"
  631. XRepeat procedure until the weights have stabilized.
  632. X.SH FILE FORMATS
  633. XThe ASCII format for input, output, and desired output values is simply one
  634. Xvalue per line.  The BINARY format is a stream of bytes, 1 byte per value.
  635. X
  636. XThe ASCII format for the weights is three values per line; which input node
  637. Xthe connection is coming from, which output node the connection is going to,
  638. Xand the weight value for that connection.  The BINARY format is a stream of
  639. Xbytes (in double floating point format) where the numbers are in the same
  640. Xorder as described for ASCII (from, to, weight, from, to, weight, ...).
  641. XInternal processing for input, output, and desired IS in double floating
  642. Xpoint.
  643. X
  644. XASCII format uses floating point numbers.  Binary is used for values (0,255)
  645. Xusing a single byte per value.
  646. X.SH SEE ALSO
  647. XR. Rosenblatt, \f2Principles of Neurodynamics\f1, New York, Spartan Books
  648. X(1959); Richard P. Lippmann, \f2An Introduction to Computing with Neural Nets\f1
  649. X.SH LIMITATIONS
  650. XOnly two functions (step & arctan) are supported.
  651. X
  652. XOnly training method is R. Rosenblatt's.
  653. X
  654. XProbably more I haven't thought of.
  655. X.SH BUGS
  656. XCould be.  This hasn't been stress-tested due to the fact that it's only a
  657. Xlab and I don't have the time :-(
  658. X.SH AUTHOR
  659. XAdam Stein
  660. X
  661. END_OF_FILE
  662.   if test 6994 -ne `wc -c <'persim.1'`; then
  663.     echo shar: \"'persim.1'\" unpacked with wrong size!
  664.   fi
  665.   # end of 'persim.1'
  666. fi
  667. if test -f 'persim.h' -a "${1}" != "-c" ; then 
  668.   echo shar: Will not clobber existing file \"'persim.h'\"
  669. else
  670.   echo shar: Extracting \"'persim.h'\" \(2784 characters\)
  671.   sed "s/^X//" >'persim.h' <<'END_OF_FILE'
  672. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  673. X
  674. X  Permission to use,  copy,  modify  and  distribute  without
  675. X  charge this software, documentation, images, etc. is grant-
  676. X  ed, provided that this copyright and the author's  name  is  
  677. X  retained.   
  678. X  
  679. X  A fee may be charged for this program ONLY to recover costs   
  680. X  for distribution (i.e. media costs).  No profit can be made            
  681. X  on this program.   
  682. X   
  683. X  The author assumes no responsibility for disasters (natural   
  684. X  or otherwise) as a consequence of use of this software.      
  685. X   
  686. X  Adam Stein (stein.wbst129@xerox.com)         
  687. X*/ 
  688. X
  689. X#define AMBIGUOUS -2                /*Ambiguous syntax*/
  690. X#define UNKNOWN -1                /*Value is unknown*/
  691. X#define VERSION_STR "v1.0 by Adam Stein"    /*Version string*/
  692. X
  693. X/*Commands*/
  694. X#define ALPHA        0        /*Alpha*/
  695. X#define EXIT        1        /*Exit program*/
  696. X#define HELP        2        /*Help*/
  697. X#define INODES        3        /*Number of input nodes*/
  698. X#define LOAD        4        /*Load variables from a file or stdin*/
  699. X#define NODE        5        /*Node command*/
  700. X#define ONODES        6        /*Number of output nodes*/
  701. X#define RANGE        7        /*Range of something*/
  702. X#define RUN        8        /*Run the simulator*/
  703. X#define SAVE        9        /*Save variables to a file*/
  704. X#define SHOW        10        /*Show the value of a variable*/
  705. X#define TRAINING    11        /*Training mode toggle*/
  706. X#define VERSION     12        /*Show version*/
  707. X
  708. X#define NUM_CMDS    13        /*Number of commands available*/
  709. X
  710. X/*Qualifiers*/
  711. X#define ASCII        50        /*File is of type ASCII*/
  712. X#define BINARY        51        /*File is of type binary (byte size)*/
  713. X#define DESIRED        52        /*Operation involves desired output*/
  714. X#define FUNCTION    53        /*Non-linearity function to use*/
  715. X#define INPUT        54        /*Operation involves input data*/
  716. X#define OUTPUT        55        /*Operation involves output data*/
  717. X#define RANDOM        56        /*Load weights randomly*/
  718. X#define STDIN        57        /*Read values from stdin*/
  719. X#define SYS_VARS    58        /*Operation involves system variables*/
  720. X#define THRESHOLD    59        /*Set node's threshold*/
  721. X#define VERBOSE        60        /*Run in verbose mode*/
  722. X#define WEIGHTS        61        /*Operation involves weight data*/
  723. X
  724. X#define NUM_QUALIFIERS    12        /*Number of qualifiers*/
  725. X
  726. X/*Command structure*/
  727. Xtypedef struct _cmd {
  728. X    int numargs;            /*Number of arguments for cmd*/
  729. X    char *name;            /*Name of command*/
  730. X} CMD;
  731. X
  732. X/*Node information structure*/
  733. Xtypedef struct _node_attr {
  734. X    double threshold;        /*Node threshold*/
  735. X    double (*func)();        /*Non-linear function*/
  736. X} NODE_ATTR;
  737. X
  738. X/*System variables structure*/
  739. Xtypedef struct _state {
  740. X    double alpha;            /*Alpha*/
  741. X    int inodes;            /*Number of input nodes*/
  742. X    int onodes;            /*Number of output nodes*/
  743. X    int training;            /*Training mode status (on/off)*/
  744. X} STATE;
  745. X
  746. X/*Structure of file containing weight information*/
  747. Xtypedef struct _weight {
  748. X    int from;            /*From input node number*/
  749. X    int to;                /*To output node number*/
  750. X    double value;            /*Weight value*/
  751. X} WEIGHT;
  752. X
  753. END_OF_FILE
  754.   if test 2784 -ne `wc -c <'persim.h'`; then
  755.     echo shar: \"'persim.h'\" unpacked with wrong size!
  756.   fi
  757.   # end of 'persim.h'
  758. fi
  759. if test -f 'read.c' -a "${1}" != "-c" ; then 
  760.   echo shar: Will not clobber existing file \"'read.c'\"
  761. else
  762.   echo shar: Extracting \"'read.c'\" \(6036 characters\)
  763.   sed "s/^X//" >'read.c' <<'END_OF_FILE'
  764. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  765. X
  766. X  Permission to use,  copy,  modify  and  distribute  without
  767. X  charge this software, documentation, images, etc. is grant-
  768. X  ed, provided that this copyright and the author's  name  is  
  769. X  retained.   
  770. X  
  771. X  A fee may be charged for this program ONLY to recover costs   
  772. X  for distribution (i.e. media costs).  No profit can be made            
  773. X  on this program.   
  774. X   
  775. X  The author assumes no responsibility for disasters (natural   
  776. X  or otherwise) as a consequence of use of this software.      
  777. X   
  778. X  Adam Stein (stein.wbst129@xerox.com)         
  779. X*/ 
  780. X
  781. X#include <stdio.h>
  782. X#include <fcntl.h>
  783. X#include "persim.h"
  784. X
  785. Xdouble atof();
  786. X
  787. X/*This routine will read in values for 1D arrays from a file or keyboard.
  788. X
  789. X  Inputs:  filename - name of the file containing the values
  790. X       filetype - what type this file it is
  791. X       numnodes - number of values to read in
  792. X       var      - which variable these values are for
  793. X  Outputs: 1 if successful, 0 if an error occurred
  794. X  Locals:  data     - used to read in data from binary files
  795. X       dummy    - used to check if there are too many values in the file
  796. X       fp       - file pointer
  797. X       loop     - loop through reading in values
  798. X  Globals: ASCII    - file is in ascii format
  799. X       EOF      - user terminated input
  800. X       NULL     - 0
  801. X*/
  802. Xreaddata(var,numnodes,filename,filetype)
  803. Xregister int numnodes,filetype;
  804. Xregister double var[];
  805. Xregister char *filename;
  806. X{
  807. X    register int loop;
  808. X    register unsigned char *data,dummy[21];
  809. X    register FILE *fp;
  810. X    char *malloc();
  811. X
  812. X    /*If filename isn't NULL, read in values from a file*/
  813. X    if(filename) {
  814. X      if((fp = fopen(filename,"r")) == NULL) {
  815. X        printf("can't open {%s}\n",filename);
  816. X        return(0);
  817. X      }
  818. X
  819. X      /*If binary, read in a line of values at a time*/
  820. X      if(filetype != ASCII) {
  821. X        if((data = (unsigned char *) malloc(numnodes)) == NULL)
  822. X          error();
  823. X
  824. X        if(fread(data,1,numnodes,fp) != numnodes) error();
  825. X
  826. X        if(fread(&dummy[0],1,1,fp) || !feof(fp))
  827. X          puts("warning: too many data points in file");
  828. X      }
  829. X
  830. X      /*Read values from ascii file or convert from binary array*/
  831. X      for(loop = 0;loop < numnodes;++loop)
  832. X        if(filetype == ASCII) {
  833. X          if(fgets(dummy,21,fp) == NULL) {
  834. X        puts("not enough data points in file");
  835. X        break;
  836. X          } else var[loop] = atof(dummy);
  837. X        } else var[loop] = (double) data[loop];
  838. X
  839. X      fclose(fp);
  840. X    } else for(loop = 0;loop < numnodes;++loop) { /*Get data from keyboard*/
  841. X         printf("Data Point #%d? ");
  842. X
  843. X         if(fgets(dummy,21,stdin) == (char *) EOF) {
  844. X           puts("input ended early at request of the user");
  845. X           break;
  846. X         } else var[loop] = atof(dummy);
  847. X           }
  848. X
  849. X    return(1);
  850. X}
  851. X
  852. X/*This routine will read in the system variables.
  853. X
  854. X  Inputs:  filename - name of the file containing the values
  855. X  Outputs: none
  856. X  Locals:  fd       - file descriptor
  857. X       tmp      - temporary holding place for read in values
  858. X  Globals: state    - system variables
  859. X       O_RDONLY - open file for reading
  860. X*/
  861. Xreadstate(filename)
  862. Xregister char *filename;
  863. X{
  864. X    register int fd;
  865. X    STATE tmp;
  866. X    extern STATE state;
  867. X
  868. X    if((fd = open(filename,O_RDONLY)) == -1) {
  869. X      printf("can't open {%s}\n",filename);
  870. X      return;
  871. X    }
  872. X
  873. X    if(read(fd,(char *) &tmp,sizeof(tmp)) != sizeof(tmp))
  874. X      puts("reading system variables failed");
  875. X    else bcopy((char *) &tmp,(char *) &state,sizeof(state));
  876. X
  877. X    close(fd);
  878. X}
  879. X
  880. X/*This routine will read in values for 2D arrays from a file or keyboard.
  881. X
  882. X  Inputs:  filename - name of the file containing the values
  883. X       filetype - what type this file it is
  884. X       innodes  - number of input nodes
  885. X       outnodes - number of output nodes
  886. X       var      - which variable these values are for
  887. X  Outputs: 1 if successful, 0 if an error occurred
  888. X  Locals:  fp       - file pointer
  889. X       from     - from which input node value
  890. X       dummy    - line of input from keyboard
  891. X       to       - to which output node value
  892. X       value    - weight value
  893. X       weight   - read in values (from, to, value)
  894. X  Globals: ASCII    - file is in ascii format
  895. X       NULL     - 0
  896. X*/
  897. Xreadwts(var,innodes,outnodes,filename,filetype)
  898. Xregister int innodes,outnodes,filetype;
  899. Xregister double *var[];
  900. Xregister char *filename;
  901. X{
  902. X    int from,to;
  903. X    double value;
  904. X    register char dummy[21];
  905. X    register FILE *fp;
  906. X    WEIGHT weight;
  907. X
  908. X    /*If filename isn't NULL, read values from a file*/
  909. X    if(filename) {
  910. X      if((fp = fopen(filename,"r")) == NULL) {
  911. X        printf("can't open {%s}\n",filename);
  912. X        return(0);
  913. X      }
  914. X
  915. X      if(filetype != ASCII)
  916. X        while(fread((char *) &weight,sizeof(weight),1,fp) == 1) {
  917. X          if((weight.from < 1) || (weight.from > innodes))
  918. X        printf("\nthe specified input node #%d is out of bounds\n\n",
  919. X               weight.from);
  920. X          else if((weight.to < 1) || (weight.to > outnodes))
  921. X             printf("\nthe specified output node #%d is out of bounds\n\n",
  922. X                    weight.to);
  923. X               else var[weight.from-1][weight.to-1] = weight.value;
  924. X        }
  925. X      else while(fscanf(fp,"%d %d %lf",&from,&to,&value) == 3) {
  926. X             if((from < 1) || (from > innodes))
  927. X           printf("\nthe specified input node #%d is out of bounds\n\n",
  928. X                  from);
  929. X             else if((to < 1) || (to > outnodes))
  930. X                printf("\nthe specified output node #%d is out of bounds\n\n",
  931. X                       to);
  932. X              else var[from-1][to-1] = value;
  933. X           }
  934. X
  935. X      fclose(fp);
  936. X    } else {
  937. X         /*Read from keyboard until user quits*/
  938. X         while(1) {
  939. X           printf("From Input Node? ");
  940. X           fgets(dummy,21,stdin);
  941. X           if(dummy[0] == '\n') break;
  942. X           from = atoi(dummy);
  943. X
  944. X           printf("To Output Node? ");
  945. X           fgets(dummy,21,stdin);
  946. X           if(dummy[0] == '\n') break;
  947. X           to = atoi(dummy);
  948. X
  949. X           printf("Weight Value? ");
  950. X           fgets(dummy,21,stdin);
  951. X           if(dummy[0] == '\n') break;
  952. X           puts("");
  953. X
  954. X               if((from < 1) || (from > innodes))
  955. X             printf("\nthe specified input node #%d is out of bounds\n\n",
  956. X                    from);
  957. X               else if((to < 1) || (to > outnodes))
  958. X                  printf("\nthe specified output node #%d is out of bounds\n\n",
  959. X                         to);
  960. X                else var[from-1][to-1] = atof(dummy);
  961. X         }
  962. X           }
  963. X
  964. X    return(1);
  965. X}
  966. X
  967. END_OF_FILE
  968.   if test 6036 -ne `wc -c <'read.c'`; then
  969.     echo shar: \"'read.c'\" unpacked with wrong size!
  970.   fi
  971.   # end of 'read.c'
  972. fi
  973. if test -f 'run.c' -a "${1}" != "-c" ; then 
  974.   echo shar: Will not clobber existing file \"'run.c'\"
  975. else
  976.   echo shar: Extracting \"'run.c'\" \(5878 characters\)
  977.   sed "s/^X//" >'run.c' <<'END_OF_FILE'
  978. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  979. X
  980. X  Permission to use,  copy,  modify  and  distribute  without
  981. X  charge this software, documentation, images, etc. is grant-
  982. X  ed, provided that this copyright and the author's  name  is  
  983. X  retained.   
  984. X  
  985. X  A fee may be charged for this program ONLY to recover costs   
  986. X  for distribution (i.e. media costs).  No profit can be made            
  987. X  on this program.   
  988. X   
  989. X  The author assumes no responsibility for disasters (natural   
  990. X  or otherwise) as a consequence of use of this software.      
  991. X   
  992. X  Adam Stein (stein.wbst129@xerox.com)         
  993. X*/ 
  994. X
  995. X#include <stdio.h>
  996. X#include <signal.h>
  997. X#include <math.h>
  998. X#include "persim.h"
  999. X
  1000. Xint quit,numepoch;
  1001. Xdouble *actual;
  1002. Xchar *calloc();
  1003. Xextern double *input,*output,*desired,**weights;
  1004. Xextern NODE_ATTR *node_attr;
  1005. Xextern STATE state;
  1006. X
  1007. X/*This routine will simulate a single layer perceptron.
  1008. X
  1009. X  Inputs:  verbose     - flag to indicate to run in verbose mode
  1010. X  Outputs: none        - 0
  1011. X  Locals:  convergence - flag indicating if weights have converged
  1012. X       loop        - loop through weights arrays
  1013. X       loop2       - loop through weights array elements
  1014. X       old_wts     - previous values of the weights
  1015. X  Globals: actual      - actual output values
  1016. X       desired     - desired output values
  1017. X       input       - input values
  1018. X       node_attr   - node attributes (function, threshold)
  1019. X       numepoch    - number of the epoch
  1020. X       quit        - flag indicating to quit simulation
  1021. X       state       - system variables
  1022. X       weights     - perceptron weights
  1023. X       NULL        - 0
  1024. X       UNKNOWN     - variable isn't set
  1025. X*/
  1026. Xvoid run(verbose)
  1027. Xregister int verbose;
  1028. X{
  1029. X    register int loop,loop2,convergence;
  1030. X    double **old_wts;
  1031. X    void quitit(),snapshot();
  1032. X
  1033. X    /*Make sure all variables needed are set*/
  1034. X    if(state.inodes == UNKNOWN) {
  1035. X      puts("the number of input nodes has not been set");
  1036. X      return;
  1037. X    }
  1038. X    if(state.onodes == UNKNOWN) {
  1039. X      puts("the number of output nodes has not been set");
  1040. X      return;
  1041. X    }
  1042. X    if(input == (double *) NULL) {
  1043. X      puts("no input data points have been loaded");
  1044. X      return;
  1045. X    }
  1046. X    if(state.training && (desired == (double *) NULL)) {
  1047. X      puts("no desired output data points have been loaded");
  1048. X      return;
  1049. X    }
  1050. X    if(node_attr == (NODE_ATTR *) NULL) {
  1051. X    puts("node thresholds and functions haven't been set");
  1052. X    return;
  1053. X    }
  1054. X
  1055. X    /*If the weights haven't been set, initialize to random values*/
  1056. X    if(weights == (double **) NULL) {
  1057. X      puts("warning: weights not set, initializing to random values");
  1058. X      randomize();
  1059. X    }
  1060. X
  1061. X    if(state.training) {
  1062. X      old_wts = (double **) NULL;
  1063. X      alloc_wts(&old_wts,state.inodes,state.onodes);
  1064. X    }
  1065. X
  1066. X    if((actual = (double *) calloc(state.onodes,sizeof(double))) == NULL)
  1067. X      error();
  1068. X
  1069. X    /*Set up signals*/
  1070. X    signal(SIGINT,quitit);
  1071. X    if(!verbose) signal(SIGTSTP,snapshot);
  1072. X
  1073. X    /*Begin simulation*/
  1074. X    convergence = quit = 0;
  1075. X    numepoch = 1;
  1076. X    while(!convergence) {
  1077. X      do_epoch();
  1078. X
  1079. X      /*If training, adjust weights until convergence*/
  1080. X      if(state.training) {
  1081. X        convergence = 1;
  1082. X        for(loop = 0;loop < state.onodes;++loop)
  1083. X          for(loop2 = 0;loop2 < state.inodes;++loop2) {
  1084. X        old_wts[loop2][loop] = weights[loop2][loop];
  1085. X            weights[loop2][loop] += (state.alpha * 
  1086. X                     (desired[loop] - actual[loop]) *
  1087. X                         input[loop2]);
  1088. X
  1089. X        if((fabs(weights[loop2][loop] - old_wts[loop2][loop]) >
  1090. X            0.000025) && !quit)
  1091. X          convergence = 0;
  1092. X          }
  1093. X
  1094. X        /*Print information if user requested verbosity*/
  1095. X        if(verbose) snapshot();
  1096. X      } else convergence = 1;
  1097. X
  1098. X      ++numepoch;
  1099. X    }
  1100. X
  1101. X    alloc_data(state.onodes,&output);
  1102. X    bcopy((char *) actual,(char *) output,state.onodes*sizeof(double));
  1103. X
  1104. X    free((char *) actual);
  1105. X    if(state.training) {
  1106. X      for(loop = 0;loop < state.inodes;++loop)
  1107. X        free((char *) old_wts[loop]);
  1108. X      free((char *) old_wts);
  1109. X    }
  1110. X
  1111. X    /*Restore signals*/
  1112. X    signal(SIGINT,SIG_DFL);
  1113. X    signal(SIGTSTP,SIG_DFL);
  1114. X}
  1115. X
  1116. X/*This routine does the calculations that make up an epoch.
  1117. X
  1118. X  Inputs:  none
  1119. X  Outputs: none
  1120. X  Locals:  loop      - loop through output nodes
  1121. X       loop2     - loop though inputs
  1122. X       sum       - sum of an output node
  1123. X  Globals: actual    - actual output values
  1124. X       input     - input values
  1125. X       node_attr - node attributes (function, threshold)
  1126. X       quit      - flag indicating to quit simulation
  1127. X       state     - system variables
  1128. X       weights   - perceptron weights
  1129. X       NULL      - 0
  1130. X*/
  1131. Xdo_epoch()
  1132. X{
  1133. X    register int loop,loop2;
  1134. X    register double sum;
  1135. X
  1136. X    for(loop = 0;loop < state.onodes;++loop) {
  1137. X      for(loop2 = 0,sum = 0.0;loop2 < state.inodes;++loop2)
  1138. X        sum += (weights[loop2][loop] * input[loop2]);
  1139. X
  1140. X      if(node_attr[loop].func == NULL) {
  1141. X        printf("the function for output node #%d hasn't been set ... quitting run\n",loop);
  1142. X        quit = 1;
  1143. X        return;
  1144. X      }
  1145. X
  1146. X      actual[loop] = node_attr[loop].func(sum - node_attr[loop].threshold);
  1147. X    }
  1148. X}
  1149. X
  1150. X/*This routine will set the weights to random numbers between 0.0 and 1.0.
  1151. X
  1152. X  Inputs:  none
  1153. X  Outputs: none
  1154. X  Locals:  from    - from which input node
  1155. X       to      - to which output node
  1156. X  Globals: state   - system variables
  1157. X       weights - perceptron weights
  1158. X*/
  1159. Xrandomize()
  1160. X{
  1161. X    register int from,to;
  1162. X    double drand48();
  1163. X
  1164. X    alloc_wts(&weights,state.inodes,state.onodes);
  1165. X
  1166. X    for(from = 0;from < state.inodes;++from)
  1167. X      for(to = 0;to < state.onodes;++to)
  1168. X        weights[from][to] = drand48();
  1169. X}
  1170. X
  1171. X/*This routine is called if ^C is pressed.  It sets up the flag to exit
  1172. X  the simulator.
  1173. X
  1174. X  Inputs:  none
  1175. X  Outputs: none
  1176. X  Locals:  none
  1177. X  Globals: quit - flag indicating to quit simulation
  1178. X*/
  1179. Xvoid quitit()
  1180. X{
  1181. X    quit = 1;
  1182. X}
  1183. X
  1184. Xvoid snapshot()
  1185. X{
  1186. X    register int loop,loop2;
  1187. X
  1188. X    printf("Epoch #%d:\n",numepoch);
  1189. X
  1190. X    for(loop = 0;loop < state.onodes;++loop)
  1191. X      printf("  Actual Output Node #%d = %lf\n",loop+1,actual[loop]);
  1192. X
  1193. X    puts("");
  1194. X
  1195. X    for(loop = 0;loop < state.inodes;++loop)
  1196. X      for(loop2 = 0;loop2 < state.onodes;++loop2)
  1197. X        printf("  [New] From #%d, To #%d, Weight = %lf\n",loop+1,loop2+1,weights[loop][loop2]);
  1198. X          
  1199. X    puts("");
  1200. X}
  1201. X
  1202. END_OF_FILE
  1203.   if test 5878 -ne `wc -c <'run.c'`; then
  1204.     echo shar: \"'run.c'\" unpacked with wrong size!
  1205.   fi
  1206.   # end of 'run.c'
  1207. fi
  1208. if test -f 'set.c' -a "${1}" != "-c" ; then 
  1209.   echo shar: Will not clobber existing file \"'set.c'\"
  1210. else
  1211.   echo shar: Extracting \"'set.c'\" \(4432 characters\)
  1212.   sed "s/^X//" >'set.c' <<'END_OF_FILE'
  1213. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  1214. X
  1215. X  Permission to use,  copy,  modify  and  distribute  without
  1216. X  charge this software, documentation, images, etc. is grant-
  1217. X  ed, provided that this copyright and the author's  name  is  
  1218. X  retained.   
  1219. X  
  1220. X  A fee may be charged for this program ONLY to recover costs   
  1221. X  for distribution (i.e. media costs).  No profit can be made            
  1222. X  on this program.   
  1223. X   
  1224. X  The author assumes no responsibility for disasters (natural   
  1225. X  or otherwise) as a consequence of use of this software.      
  1226. X   
  1227. X  Adam Stein (stein.wbst129@xerox.com)         
  1228. X*/ 
  1229. X
  1230. X#include <stdio.h>
  1231. X#include <math.h>
  1232. X#include "persim.h"
  1233. X
  1234. Xextern NODE_ATTR *node_attr;
  1235. Xextern STATE state;
  1236. X
  1237. X/*This routine will set a variable to an integer number.
  1238. X
  1239. X  Inputs:  number    - number to set variable to
  1240. X       var       - variable to set
  1241. X  Outputs: none
  1242. X  Locals:  loop      - loop through output nodes
  1243. X  Globals: input     - input values array
  1244. X       node_attr - node attributes (function, threshold)
  1245. X       output    - output values array
  1246. X       state     - system variables
  1247. X       INODES    - set number of input nodes variable
  1248. X       ONODES    - set number of output nodes variable
  1249. X       NULL      - 0
  1250. X*/
  1251. Xvoid iset(var,number)
  1252. Xregister int var,number;
  1253. X{
  1254. X    register int loop;
  1255. X    char *calloc();
  1256. X    extern double *input,*output;
  1257. X
  1258. X    switch(var) {
  1259. X      case INODES:
  1260. X        if(number < 1) puts("illegal value for number of input nodes");
  1261. X        else {
  1262. X               if(input != (double *) NULL)
  1263. X             resize_io(&input,number);
  1264. X
  1265. X               state.inodes = number;
  1266. X             }
  1267. X        break;
  1268. X      case ONODES:
  1269. X        if(number < 1) puts("illegal value for number of output nodes");
  1270. X        else {
  1271. X               if(output != (double *) NULL) resize_io(&output,number);
  1272. X               if(node_attr != (NODE_ATTR *) NULL)
  1273. X             resize_attr(&node_attr,number);
  1274. X               else if((node_attr = (NODE_ATTR *) calloc(number,
  1275. X                              sizeof(NODE_ATTR)))
  1276. X                              == NULL)
  1277. X                  error();
  1278. X
  1279. X               for(loop = 0;loop < state.onodes;++loop)
  1280. X             node_attr[loop].func = NULL;
  1281. X
  1282. X               state.onodes = number;
  1283. X             }
  1284. X        break;
  1285. X    }
  1286. X}
  1287. X
  1288. X/*This routine will set a variable to a floating point number.
  1289. X
  1290. X  Inputs:  number - number to set variable to
  1291. X       var      - variable to set
  1292. X  Outputs: none
  1293. X  Locals:  none
  1294. X  Globals: state  - system variables
  1295. X       ALPHA  - set alpha
  1296. X*/
  1297. Xvoid fpset(var,number)
  1298. Xregister int var;
  1299. Xregister double number;
  1300. X{
  1301. X    switch(var) {
  1302. X      case ALPHA:
  1303. X        if((number < 0.0) || (number > 1.0))
  1304. X          puts("illegal value for alpha");
  1305. X        else state.alpha = number;
  1306. X        break;
  1307. X    }
  1308. X}
  1309. X
  1310. X/*This routine will set the threshold level of an output node.
  1311. X
  1312. X  Inputs:  value      - threshold level
  1313. X       whichnnode - which node to set (-1 means ALL nodes)
  1314. X  Outputs: none
  1315. X  Locals:  loop          - loop through output nodes
  1316. X  Globals: node_attr  - node attributes (function, threshold)
  1317. X       state      - system variables
  1318. X       NULL       - 0
  1319. X*/
  1320. Xvoid set_threshold(whichnode,value)
  1321. Xregister int whichnode;
  1322. Xregister double value;
  1323. X{
  1324. X    register int loop;
  1325. X
  1326. X    if(node_attr == (NODE_ATTR *) NULL) {
  1327. X      puts("the number of output nodes has not been set yet");
  1328. X      return;
  1329. X    }
  1330. X
  1331. X    if(whichnode == -1)
  1332. X      for(loop = 0;loop < state.onodes;++loop)
  1333. X        node_attr[loop].threshold = value;
  1334. X    else node_attr[whichnode-1].threshold = value;
  1335. X}
  1336. X
  1337. X/*This routine will set the function of an output node.
  1338. X
  1339. X  Inputs:  string     - function to set
  1340. X       whichnnode - which node to set (-1 means ALL nodes)
  1341. X  Outputs: none
  1342. X  Locals:  loop          - loop through output nodes
  1343. X  Globals: node_attr  - node attributes (function, threshold)
  1344. X       state      - system variables
  1345. X       NULL       - 0
  1346. X*/
  1347. Xvoid set_func(whichnode,string)
  1348. Xregister int whichnode;
  1349. Xregister char *string;
  1350. X{
  1351. X    register int loop;
  1352. X
  1353. X    if(node_attr == (NODE_ATTR *) NULL) {
  1354. X      puts("the number of output nodes has not been set yet");
  1355. X      return;
  1356. X    }
  1357. X
  1358. X    if(whichnode == -1) {
  1359. X      for(loop = 0;loop < state.onodes;++loop)
  1360. X        if(!_set_func(string,&node_attr[loop]))
  1361. X          puts("illegal function");
  1362. X    } else if(!_set_func(string,&node_attr[whichnode-1]))
  1363. X         puts("illegal function");
  1364. X}
  1365. X
  1366. X/*This routine will set the correct function pointer based on function name.
  1367. X  
  1368. X  Inputs:  node   - which output node to set
  1369. X       string - function to set it to
  1370. X  Outputs: none
  1371. X  Locals:  none
  1372. X  Globals: none
  1373. X*/
  1374. X_set_func(string,node)
  1375. Xregister char *string;
  1376. Xregister NODE_ATTR *node;
  1377. X{
  1378. X    double step();
  1379. X
  1380. X    if(!strcmp(string,"step")) node->func = step;
  1381. X    else if(!strcmp(string,"arctan")) node->func = atan;
  1382. X}
  1383. X
  1384. END_OF_FILE
  1385.   if test 4432 -ne `wc -c <'set.c'`; then
  1386.     echo shar: \"'set.c'\" unpacked with wrong size!
  1387.   fi
  1388.   # end of 'set.c'
  1389. fi
  1390. if test -f 'show.c' -a "${1}" != "-c" ; then 
  1391.   echo shar: Will not clobber existing file \"'show.c'\"
  1392. else
  1393.   echo shar: Extracting \"'show.c'\" \(5153 characters\)
  1394.   sed "s/^X//" >'show.c' <<'END_OF_FILE'
  1395. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  1396. X
  1397. X  Permission to use,  copy,  modify  and  distribute  without
  1398. X  charge this software, documentation, images, etc. is grant-
  1399. X  ed, provided that this copyright and the author's  name  is  
  1400. X  retained.   
  1401. X  
  1402. X  A fee may be charged for this program ONLY to recover costs   
  1403. X  for distribution (i.e. media costs).  No profit can be made            
  1404. X  on this program.   
  1405. X   
  1406. X  The author assumes no responsibility for disasters (natural   
  1407. X  or otherwise) as a consequence of use of this software.      
  1408. X   
  1409. X  Adam Stein (stein.wbst129@xerox.com)         
  1410. X*/ 
  1411. X
  1412. X#include <stdio.h>
  1413. X#include <math.h>
  1414. X#include "persim.h"
  1415. X
  1416. X/*This routine will show the values of different variables.
  1417. X
  1418. X  Inputs:  var        - which variable to display
  1419. X       whichnode  - in the case of output node attributes, which node
  1420. X  Outputs: none
  1421. X  Locals:  loop       - loop through variable elements
  1422. X       loop2      - loop through variable elements (for 2D arrays)
  1423. X  Globals: desired    - desired output values
  1424. X       input      - intput values
  1425. X       output     - output values
  1426. X       node_attr  - node attributes (function, threshold)
  1427. X       print_line - flag indicating if commands are from a batch file
  1428. X       ranges     - max and min values (only for step function right now)
  1429. X       state      - system variables
  1430. X       weights    - perceptron weights
  1431. X       ALPHA      - show alpha
  1432. X       AMBIGUOUS  - ambiguous variable specified
  1433. X       DESIRED    - show desired output values
  1434. X       NULL       - 0
  1435. X       INODES     - show number of input nodes
  1436. X       INPUT      - show input values
  1437. X       NODE       - show node attributes
  1438. X       ONODES     - show number of output nodes
  1439. X       OUTPUT     - show output values
  1440. X       RANGE      - show ranges
  1441. X       SYS_VARS   - show system variables
  1442. X       UNKNOWN    - variable isn't set
  1443. X       TRAINING   - show status of training mode
  1444. X       WEIGHTS    - show perceptron weights
  1445. X*/
  1446. Xshow(var,whichnode)
  1447. Xregister int var,whichnode;
  1448. X{
  1449. X    register int loop,loop2;
  1450. X    extern int print_line;
  1451. X    extern double *input,*output,*desired,**weights,ranges[1][2];
  1452. X    extern NODE_ATTR *node_attr;
  1453. X    extern STATE state;
  1454. X
  1455. X    switch(var) {
  1456. X      case ALPHA:
  1457. X        printf("Alpha is currently set to %lf\n",state.alpha);
  1458. X        break;
  1459. X      case AMBIGUOUS:
  1460. X        puts("*** ambiguous variable to show ***");
  1461. X        break;
  1462. X      case DESIRED:
  1463. X        if(desired == (double *) NULL)
  1464. X          puts("no desired output data points have been loaded");
  1465. X        else
  1466. X          for(loop = 0;loop < state.onodes;++loop)
  1467. X            printf("Desired Output Data Point #%d = %lf\n",loop+1,desired[loop]);
  1468. X        break;
  1469. X      case INODES:
  1470. X        if(state.inodes == UNKNOWN)
  1471. X          puts("The number of input nodes has not been set");
  1472. X        else
  1473. X          printf("The number of input nodes is currently set to %d\n",
  1474. X             state.inodes);
  1475. X        break;
  1476. X      case INPUT:
  1477. X        if(input == (double *) NULL)
  1478. X          puts("no input data points have been loaded");
  1479. X        else
  1480. X          for(loop = 0;loop < state.inodes;++loop)
  1481. X            printf("Input Data Point #%d = %lf\n",loop+1,input[loop]);
  1482. X        break;
  1483. X      case NODE:
  1484. X        if(node_attr == (NODE_ATTR *) NULL)
  1485. X          puts("no node attributes have been set");
  1486. X        else if(whichnode == -1)
  1487. X               for(loop = 0;loop < state.onodes;++loop)
  1488. X             show_node(loop+1,node_attr[loop]);
  1489. X             else show_node(whichnode,node_attr[whichnode-1]);
  1490. X        break;
  1491. X      case ONODES:
  1492. X        if(state.onodes == UNKNOWN)
  1493. X          puts("The number of output nodes has not been set");
  1494. X        else
  1495. X          printf("The number of output nodes is currently set to %d\n",
  1496. X             state.onodes);
  1497. X        break;
  1498. X      case OUTPUT:
  1499. X        if(output == (double *) NULL)
  1500. X          puts("no output data points have generated");
  1501. X        else
  1502. X          for(loop = 0;loop < state.onodes;++loop)
  1503. X            printf("Output Data Point #%d = %lf\n",loop+1,output[loop]);
  1504. X        break;
  1505. X      case RANGE:
  1506. X        puts("Step Function:");
  1507. X        printf("  min: %lf, max: %lf\n",ranges[0][0],ranges[0][1]);
  1508. X        break;
  1509. X      case SYS_VARS:
  1510. X        puts("System Variables:");
  1511. X        printf("  alpha = %lf\n",state.alpha);
  1512. X
  1513. X        printf("  inodes = ");
  1514. X        if(state.inodes == UNKNOWN) puts("NOT SET");
  1515. X        else printf("%d\n",state.inodes);
  1516. X
  1517. X        printf("  onodes = ");
  1518. X        if(state.onodes == UNKNOWN) puts("NOT SET");
  1519. X        else printf("%d\n",state.onodes);
  1520. X
  1521. X        printf("  training mode is ");
  1522. X        if(state.training) puts("ON");
  1523. X        else puts("OFF");
  1524. X        break;
  1525. X      case TRAINING:
  1526. X        printf("training mode is ");
  1527. X        if(state.training) puts("ON");
  1528. X        else puts("OFF");
  1529. X        break;
  1530. X      case WEIGHTS:
  1531. X        if(weights == (double **) NULL)
  1532. X          puts("no weights have been loaded");
  1533. X        else
  1534. X          for(loop = 0;loop < state.inodes;++loop)
  1535. X            for(loop2 = 0;loop2 < state.onodes;++loop2)
  1536. X              if(weights[loop][loop2] != 0.0)
  1537. X            printf("From Input Node #%d, To Output Node #%d, Weight = %lf\n",
  1538. X                   loop+1,loop2+1,weights[loop][loop2]);
  1539. X        break;
  1540. X    }
  1541. X}
  1542. X
  1543. X/*This routine will show the attributes of an output node.
  1544. X
  1545. X  Inputs:  node      - node attributes
  1546. X       whichnode - which node to display information about
  1547. X  Outputs: none
  1548. X  Locals:  none
  1549. X  Globals: none
  1550. X*/
  1551. Xshow_node(whichnode,node)
  1552. Xregister int whichnode;
  1553. XNODE_ATTR node;
  1554. X{
  1555. X    double step();
  1556. X
  1557. X    printf("Output Node #%d: threshold = %lf, function = ",whichnode,
  1558. X                                   node.threshold);
  1559. X    
  1560. X    if(node.func == atan) puts("arctan");
  1561. X    else if(node.func == step) puts("step");
  1562. X         else  puts("NULL");
  1563. X}
  1564. X
  1565. END_OF_FILE
  1566.   if test 5153 -ne `wc -c <'show.c'`; then
  1567.     echo shar: \"'show.c'\" unpacked with wrong size!
  1568.   fi
  1569.   # end of 'show.c'
  1570. fi
  1571. if test -f 'write.c' -a "${1}" != "-c" ; then 
  1572.   echo shar: Will not clobber existing file \"'write.c'\"
  1573. else
  1574.   echo shar: Extracting \"'write.c'\" \(3632 characters\)
  1575.   sed "s/^X//" >'write.c' <<'END_OF_FILE'
  1576. X/*Copyright  (c)   1992  Adam  Stein.   All  Rights Reserved.   
  1577. X
  1578. X  Permission to use,  copy,  modify  and  distribute  without
  1579. X  charge this software, documentation, images, etc. is grant-
  1580. X  ed, provided that this copyright and the author's  name  is  
  1581. X  retained.   
  1582. X  
  1583. X  A fee may be charged for this program ONLY to recover costs   
  1584. X  for distribution (i.e. media costs).  No profit can be made            
  1585. X  on this program.   
  1586. X   
  1587. X  The author assumes no responsibility for disasters (natural   
  1588. X  or otherwise) as a consequence of use of this software.      
  1589. X   
  1590. X  Adam Stein (stein.wbst129@xerox.com)         
  1591. X*/ 
  1592. X
  1593. X#include <stdio.h>
  1594. X#include <fcntl.h>
  1595. X#include "persim.h"
  1596. X
  1597. X/*This routine will write values for 1D arrays to a file.
  1598. X
  1599. X  Inputs:  filename - name of the file to write to
  1600. X       filetype - what type this file it is
  1601. X       numnodes - number of values to write out
  1602. X       var      - which variable to write out
  1603. X  Outputs: none
  1604. X  Locals:  data        - line of data to write out
  1605. X       fp       - file pointer
  1606. X       loop     - loop through writing out values
  1607. X  Globals: ASCII    - write out in ascii format
  1608. X       NULL     - 0
  1609. X*/
  1610. Xwritedata(var,numnodes,filename,filetype)
  1611. Xregister int numnodes,filetype;
  1612. Xregister double var[];
  1613. Xregister char *filename;
  1614. X{
  1615. X    register int loop;
  1616. X    register unsigned char *data;
  1617. X    register FILE *fp;
  1618. X    char *malloc();
  1619. X
  1620. X    if((fp = fopen(filename,"w")) == NULL) {
  1621. X          printf("can't open {%s}\n",filename);
  1622. X      return;
  1623. X        }
  1624. X
  1625. X    if((data = (unsigned char *) malloc(numnodes)) == NULL)
  1626. X      error();
  1627. X
  1628. X    for(loop = 0;loop < numnodes;++loop)
  1629. X      if(filetype == ASCII) fprintf(fp,"%d\n",(int) var[loop]);
  1630. X      else data[loop] = (unsigned char) var[loop];
  1631. X
  1632. X    if(filetype != ASCII)
  1633. X      if(fwrite(data,1,numnodes,fp) != numnodes) error();
  1634. X
  1635. X    fclose(fp);
  1636. X}
  1637. X
  1638. X/*This routine will write out the system variables.
  1639. X
  1640. X  Inputs:  filename - name of the file to write to
  1641. X  Outputs: none
  1642. X  Locals:  fd        - file descriptor
  1643. X  Globals: state    - system variables
  1644. X       O_CREAT  - create file if necessary
  1645. X       O_RDONLY - open file for reading
  1646. X       O_WRONLY - open file for writing
  1647. X*/
  1648. Xwritestate(filename)
  1649. Xregister char *filename;
  1650. X{
  1651. X    register int fd;
  1652. X    extern STATE state;
  1653. X
  1654. X    if((fd = open(filename,O_RDONLY)) != -1) {
  1655. X      close(fd);
  1656. X      printf("{%s} already exists\n",filename);
  1657. X      return;
  1658. X    }
  1659. X
  1660. X    if((fd = open(filename,O_WRONLY|O_CREAT,0644)) == -1) {
  1661. X      printf("can't open {%s}\n",filename);
  1662. X      return;
  1663. X    }
  1664. X
  1665. X    if(write(fd,(char *) &state,sizeof(state)) != sizeof(state))
  1666. X      puts("writing system variables failed");
  1667. X
  1668. X    close(fd);
  1669. X}
  1670. X
  1671. X/*This function will write the values from a 2D array to a file.
  1672. X
  1673. X  Inputs:  filename - name of the file to write to
  1674. X       filetype - what type this file it is
  1675. X       innodes  - number of input nodes
  1676. X       outnodes - number of output nodes
  1677. X       var      - which variable to write out
  1678. X  Outputs: none
  1679. X  Locals:  fd       - file descriptor
  1680. X  Globals: ASCII    - write out in ascii format
  1681. X       NULL     - 0
  1682. X
  1683. X*/
  1684. Xwritewts(var,innodes,outnodes,filename,filetype)
  1685. Xregister int innodes,outnodes,filetype;
  1686. Xregister double *var[];
  1687. Xregister char *filename;
  1688. X{
  1689. X    register int loop,loop2;
  1690. X    register FILE *fp;
  1691. X    WEIGHT weight;
  1692. X
  1693. X    if((fp = fopen(filename,"w")) == NULL) {
  1694. X          printf("can't open {%s}\n",filename);
  1695. X          return;
  1696. X        }
  1697. X
  1698. X    for(loop = 0;loop < innodes;++loop)
  1699. X      for(loop2 = 0;loop2 < outnodes;++loop2)
  1700. X        if(var[loop][loop2] != 0.0)
  1701. X          if(filetype != ASCII) {
  1702. X        weight.from = loop+1;
  1703. X        weight.to = loop2+1;
  1704. X        weight.value = var[loop][loop2];
  1705. X            if(fwrite((char *) &weight,sizeof(weight),1,fp) != 1)
  1706. X          error();
  1707. X          } else fprintf(fp,"%d %d %lf\n",loop+1,loop2+1,var[loop][loop2]);
  1708. X
  1709. X    fclose(fp);
  1710. X}
  1711. X
  1712. END_OF_FILE
  1713.   if test 3632 -ne `wc -c <'write.c'`; then
  1714.     echo shar: \"'write.c'\" unpacked with wrong size!
  1715.   fi
  1716.   # end of 'write.c'
  1717. fi
  1718. echo shar: End of archive 1 \(of 3\).
  1719. cp /dev/null ark1isdone
  1720. MISSING=""
  1721. for I in 1 2 3 ; do
  1722.     if test ! -f ark${I}isdone ; then
  1723.     MISSING="${MISSING} ${I}"
  1724.     fi
  1725. done
  1726. if test "${MISSING}" = "" ; then
  1727.     echo You have unpacked all 3 archives.
  1728.     rm -f ark[1-9]isdone
  1729. else
  1730.     echo You still must unpack the following archives:
  1731.     echo "        " ${MISSING}
  1732. fi
  1733. exit 0
  1734. exit 0 # Just in case...
  1735.