home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 521.lha / Chi-Square / BASICcode next >
Encoding:
Text File  |  1991-06-10  |  9.4 KB  |  425 lines

  1. WINDOW 1,"Chi-Square Test",(0,0)-(640,200),31+256
  2.  
  3. DEFDBL D,a,b,e-g,p,s,t,x
  4. DEFINT i-k,c,n,r
  5.  
  6. LIBRARY "requester.library"
  7.   DECLARE FUNCTION DoFileIOWindow&() LIBRARY
  8.   DECLARE FUNCTION GetFileIO&() LIBRARY
  9.   DECLARE FUNCTION AutoFileMessage() LIBRARY
  10.  
  11. ' subroutine to call file requestor from the requester.library.
  12.  
  13. '      ireqx,ireqy x and y coordinates for the requestor
  14. '      WindowTitle$ a title displayed in the requestor's title bar
  15. '      Values returned by the subroutine:
  16. '           PathName$    full path for selected file
  17. '           FileName$    file name only
  18. '           VolName$     the volume name or drive id
  19. '           DrawerName$  drawer name or subdirectory
  20. '           DiscOrDir%   returns 1 if selection is a drive or directory only
  21. '           NoExist%     returns 1 if file does not exist
  22. '           flag%        returns 0 if request fails and 1 if successful
  23. '           Reason$      short message explaining failure
  24. '
  25. SUB requestor(ireqx,ireqy,WindowTitle$,PathName$,FileName$,VolName$,DrawerName$,DiscOrDir%,NoExist%,flag%,reason$)
  26.     LOCAL i,value
  27.     DEFINT i,value
  28.     DiscOrDir%=0 : NoExist%=0 : flag%=0
  29.     PathName$="" : FileName$="" : VolName$="" : DrawerName$=""
  30.     reason$=""
  31.     PathBuffer$=SPACE$(202)
  32.     ExtPtrBuff$=SPACE$(24)
  33.     FileIO&=GetFileIO&()
  34.     IF FileIO&=0 THEN
  35.         CALL ReleaseFileIO&(FileIO&)
  36.         flag%=0
  37.         reason$="FileIO Failed"
  38.         EXIT SUB
  39.     END IF
  40.     POKEL FileIO&+248,SADD(PathBuffer$)
  41.     POKEL FileIO&+222,SADD(ExtPtrBuff$)
  42.     POKEL FileIO&+244,SADD(WindowTitle$+CHR$(0))
  43.     POKE FileIO&+261,1
  44.     POKE FileIO&+262,1
  45.     POKE FileIO&+263,0
  46.     POKEW FileIO&+232,ireqx
  47.     POKEW FileIO&+234,ireqy
  48.     POKE FileIO&+1,4
  49.     extsize&=LEN(ext$)
  50.     POKE FileIO&+1,128
  51.     result&=DoFileIOWindow&(FileIO&,0&)
  52.     IF result&=-1 THEN
  53.         CALL ResetTitle(FileIO,WINDOW(7))
  54.         CALL ReleaseFileIO(FileIO)
  55.         flag%=0
  56.         reason$="Cancel"
  57.         EXIT SUB
  58.     END IF
  59.     IF result&=0 THEN
  60.         result&=AutoFileMessage&(0&,WINDOW(7))
  61.         INPUT "Type path: ";PathName$
  62.         CALL ParseString&(FileIO&,SADD(PathName$+CHR$(0)))
  63.         GOTO CopyFN
  64.     END IF
  65.  
  66.     pathname$ = ""
  67.         FOR i = 0 TO 202
  68.             value = PEEK(SADD(PathBuffer$)+i)
  69.             IF value = 0 THEN EXIT FOR
  70.             char$ = CHR$(value)
  71.             pathname$ = pathname$+char$
  72.         NEXT i 
  73.  
  74.     CopyFN: 'Copy out the Filename to Filename$.
  75.         FileName$ = ""
  76.         FOR i = 0 TO 30
  77.             value = PEEK(FileIO&+2+i)
  78.             IF value = 0 THEN EXIT FOR
  79.             char$ = CHR$(value)
  80.             FileName$ = FileName$+char$
  81.         NEXT i
  82.  
  83.     CopyDrawer: 'Copy out all the drawers 
  84.         DrawerName$ = ""
  85.         FOR i = 0 TO 132
  86.             value = PEEK(FileIO&+32+i)
  87.             IF value = 0 THEN EXIT FOR
  88.             char$ = CHR$(value)
  89.             DrawerName$ = DrawerName$+char$
  90.         NEXT i
  91.  
  92.     CopyVol: 'Copy out the diskname 
  93.         VolName$ = ""
  94.         FOR i = 0 TO 30
  95.             value = PEEK(FileIO&+164+i)
  96.             IF value = 0 THEN EXIT FOR
  97.             char$ = CHR$(value)
  98.             VolName$ = VolName$+char$
  99.         NEXT i
  100.  
  101.     extsize&=LEN(FileName$)
  102.     IF extsize&=0 THEN DiscOrDir%=1
  103.     IF PEEKL(FileIO&+240)=0 THEN NoExist%=1
  104.     CALL ResetTitle&(FileIO&,WINDOW(7))
  105.     CALL ReleaseFileIO&(FileIO&)
  106.     flag%=1
  107. END SUB
  108.  
  109. 'subroutine to print message at line linenum1%, then wait for key press
  110. 'key press message is printed at line linenum2%
  111.  
  112. SUB message (VAL linenum1%, VAL linenum2%, VAL m$)
  113.     LOCATE linenum1%,INT((80-LEN(m$))/2) : ?m$;
  114.     LOCATE linenum2%,27,0 : ?"Press any key to continue";
  115.     DO 
  116.         IF INKEY$<>"" THEN EXIT LOOP
  117.         SLEEP
  118.     LOOP
  119.     CLS : LOCATE 1,1,1 
  120. END SUB
  121.  
  122. 'subroutine to ask if user wants to continue
  123. 'returns flag%=0 if no, flag%=1 if yes
  124.  
  125. SUB continue (flag%)
  126.     LOCAL t$ : t$="" : flag% = 0
  127.     WHILE t$<>"YES" AND t$<>"NO" AND t$<>"Y" AND t$<>"N"
  128.         CLS : LOCATE 12,32 : INPUT "Try again? ",t$
  129.         t$=UCASE$(t$)
  130.         IF t$="YES" OR t$="Y" THEN
  131.             flag%=1 : EXIT SUB
  132.         END IF
  133.         IF t$="NO" OR t$="N" THEN
  134.             flag%=0 : EXIT SUB
  135.         END IF
  136.     WEND
  137. END SUB
  138.  
  139. 'ln(Gamma) function
  140.  
  141. FUNCTION gammln(VAL xx)
  142.     LOCAL stp,x,tmp,ser
  143.     stp=2.50662827465
  144.     x=xx-1.0
  145.     tmp=x+5.5
  146.     tmp=(x+0.5)*LOG(tmp)-tmp
  147.     ser=1.0+76.18009173/(x+1.0)-86.50532033/(x+2.0)+24.01409822/(x+3.0)
  148.     ser=ser-1.231739516/(x+4.0)+0.120858003e-2/(x+5.0)
  149.     ser=ser-0.536382e-5/(x+6.0)
  150.     gammln=tmp+LOG(stp*ser)
  151. END FUNCTION
  152.  
  153. 'incomplete Gamma function by series representation
  154.  
  155. SUB gser (VAL a,VAL x,gamser,gln)
  156.     LOCAL itmax,eps,n,sum,del,ap
  157.     itmax=100
  158.     eps=3.0e-7
  159.     gln=gammln(a)
  160.     IF x<=0.0 THEN 
  161.         IF x<0.0 THEN ? "**note** gser: x<0"
  162.         gamser=0.0
  163.     ELSE
  164.         ap=a
  165.         sum=1.0/a
  166.         del=sum
  167.         FOR n=1 TO itmax
  168.             ap=ap+1.0
  169.             del=del*x/ap
  170.             sum=sum+del
  171.             IF ABS(del)<ABS(sum)*eps THEN GOTO gserlabel
  172.         NEXT n
  173.         ? "**note** gser: a too large, itmax too small"
  174. gserlabel:    gamser=sum*EXP(-x+a*LOG(x)-gln)
  175.     END IF
  176. END SUB
  177.  
  178. 'incomplete gamma function by continued fraction representation
  179.  
  180. SUB gcf(VAL a,VAL x, gammcf,gln)
  181.     LOCAL itmax,eps,n,gold,g,fac,b1,b0,anf,ana,an,a1,a0
  182.     itmax=100
  183.     eps=3.0e-7
  184.     gln=gammln(a)
  185.     gold=0.0
  186.     a0=1.0
  187.     a1=x
  188.     b0=0.0
  189.     b1=1.0
  190.     fac=1.0
  191.     FOR n=1 TO itmax
  192.         an=1.0*n
  193.         ana=an-a
  194.         a0=(a1+a0*ana)*fac
  195.         b0=(b1+b0*ana)*fac
  196.         anf=an*fac
  197.         a1=x*a0+anf*a1
  198.         b1=x*b0+anf*b1
  199.         IF a1<>0.0 THEN
  200.             fac=1.0/a1
  201.             g=b1*fac
  202.             IF ABS((g-gold)/g)<eps THEN GOTO gcflabel
  203.             gold=g
  204.         END IF
  205.     NEXT n
  206.     ? "**note** gcf: a too large, itmax too small"
  207. gcflabel:  gammcf=EXP(-x+a*LOG(x)-gln)*g
  208. END SUB        
  209.  
  210. 'incomplete Gamma function Q(a,x)=1-P(a,x)
  211.  
  212. FUNCTION gammq(VAL a,VAL x)
  213.     LOCAL gamser,gammcf,gln
  214.     IF (x<0.0) OR (a<=0.0) THEN
  215.         ? "**OOPS!** gammq: invalid arguments"
  216.     END IF
  217.     IF x<a+1.0 THEN
  218.         gser a,x,gamser,gln
  219.         gammq=1.0-gamser
  220.     ELSE
  221.         gcf a,x,gammcf,gln
  222.         gammq=gammcf
  223.     END IF
  224. END FUNCTION
  225.                 
  226. 'print instructions
  227.  
  228. CLS
  229. ? : ? : ?
  230. ?"This program will allow you to select a data file, and then calculate"
  231. ?"  the Chi-square parameter and p value from that file.  The data file"
  232. ?"   MUST be of a certain format."
  233. ?
  234. ?"  WARNING: This program will NOT accept files that do not conform to"
  235. ?"           the expected format!"
  236. ?
  237. ?"The format is the number of columns (MUST be an integer), followed"
  238. ?"  by the number of rows (MUST be an integer), followed by the data"
  239. ?"  table itself.  For example, an acceptable 3 x 2 table file would"
  240. ?"  be:"
  241. ?
  242. ?"          3   2"
  243. ?"          24  11  15"
  244. ?"          12  14   3"
  245. message 23,23,""
  246. ?
  247. ?"You may use your favorite word processor, spreadsheet, or whatever to"
  248. ?"  generate the data file.  However, the file MUST be in ASCII.  This"
  249. ?"  is actually pretty simple--it usually just means selecting the"
  250. ?"  ""general"" option when saving the file from your word processor, or"
  251. ?"  the ""print to file"" option when saving the file from your"
  252. ?"  spreadsheet."
  253. ?
  254. ?"Note:  the program does not care about spaces in a file.  It DOES however"
  255. ?"  care about carriage returns, and will treat them as zeros.  IF YOU"
  256. ?"  HAVE EXTRA CARRIAGE RETURNS IN YOUR DATA FILE, DELETE THEM PRIOR TO"
  257. ?"  RUNNING THIS PROGRAM!  Only put carriage returns at the end of a"
  258. ?"  line of data, and no extra lines."
  259. message 19,23,"Happy Analyzing!     C. Niederberger 2/91" 
  260.  
  261. start:    CLS
  262.  
  263. CALL requestor (10,10,"Select Data File",Name$,f$,v$,d$,dod%,ne%,f%,r$)
  264.  
  265. IF dod%=1 OR ne%=1 OR f%=0 THEN
  266.     CLS : message 11,13,"File lookup failed: "+r$
  267.     continue flg%
  268.     IF flg%=0 THEN GOTO finish ELSE GOTO start
  269. END IF
  270.  
  271. OPEN Name$ FOR INPUT AS #1
  272.  
  273. 'load data array with data from file
  274.  
  275. INPUT #1,Dnc    'nc = Dnc = number of columns
  276.  
  277. nc=INT(Dnc)
  278. IF Dnc<>nc THEN
  279.     CLOSE #1
  280.     CLS : message 11,13,"number of columns is not an integer!"
  281.     continue flg%
  282.     IF flg%=0 THEN
  283.         GOTO finish
  284.     ELSE
  285.         ERASE DObs, DExd, DSumRow, DSumCol
  286.         GOTO start
  287.     END IF
  288. END IF
  289.  
  290. INPUT #1,Dnr    'nr = Dnr = number of rows
  291.  
  292. nr=INT(Dnr)
  293. IF Dnr<>nr THEN
  294.     CLOSE #1
  295.     CLS : message 11,13,"number of rows is not an integer!"
  296.     continue flg%
  297.     IF flg%=0 THEN
  298.         GOTO finish
  299.     ELSE
  300.         ERASE DObs, DExd, DSumRow, DSumCol
  301.         GOTO start
  302.     END IF
  303. END IF
  304.  
  305. DIM DObs(nc,nr)
  306. DIM DExd(nc,nr)
  307. DIM DSumRow(nr)
  308. DIM DSumCol(nc)
  309.  
  310. DSum=0
  311. FOR r=1 TO nr
  312.     DSumRow(r)=0
  313.     FOR c=1 TO nc
  314.     IF EOF(1) THEN
  315.         CLOSE #1
  316.         CLS : message 11,13,"Not enough data in table!"
  317.         continue flg%
  318.         IF flg%=0 THEN
  319.             GOTO finish
  320.         ELSE
  321.             ERASE DObs, DExd, DSumRow, DSumCol
  322.             GOTO start
  323.         END IF
  324.     END IF
  325.         INPUT #1,DObs(c,r)
  326.         DSumRow(r)=DSumRow(r)+DObs(c,r)
  327.         DSum=DSum+DObs(c,r)
  328.     NEXT c
  329. NEXT r
  330.  
  331. IF NOT EOF(1) THEN
  332.     CLOSE #1
  333.     CLS : message 11,13,"Too much data in table!"
  334.     continue flg%
  335.     IF flg%=0 THEN
  336.         GOTO finish
  337.     ELSE
  338.         ERASE DObs, DExd, DSumRow, DSumCol
  339.         GOTO start
  340.     END IF
  341. END IF
  342.  
  343. CLOSE #1
  344.  
  345. 'calculate column sums
  346.  
  347. FOR c=1 TO nc
  348.     DSumCol(c)=0
  349.     FOR r=1 TO nr
  350.         DSumCol(c)=DSumCol(c)+DObs(c,r)
  351.     NEXT r
  352. NEXT c
  353.  
  354. 'calculate expected table and Chi-Square
  355.  
  356. DChiSqr=0
  357. FOR c=1 TO nc
  358.     FOR r=1 TO nr
  359.         DExd(c,r)=DSumRow(r)*DSumCol(c)/DSum
  360.         DChiSqr=DChiSqr+(((DObs(c,r)-DExd(c,r))^2)/DExd(c,r))
  361.     NEXT r
  362. NEXT c
  363.  
  364. 'print Chi-square results
  365. 'calculate and print significance level
  366.  
  367. ? : ? : ? : ? : ? : ?
  368. ndf=(nr-1)*(nc-1)
  369. ? "     For"ndf"degree(s) of freedom, Chi-Square ="DChiSqr
  370. ?
  371. prob=gammq(0.5*ndf,0.5*DChiSqr)
  372. IF prob<1E-15 THEN 
  373.     ?"     significance level p="prob
  374.     ?
  375.     ?"     !! significance level p <.000000000000001 !!"
  376.     GOTO waituser
  377. END IF
  378. nzeros=INT(ABS(LOG10(prob))) : ans$="."
  379. nmant=INT(10^(nzeros+1)*prob+1) : nmant$=RIGHT$(STR$(nmant),1)
  380. IF nmant$="0" THEN
  381.     nmant$="1"
  382.     nzeros=nzeros-1
  383. END IF
  384. IF prob>=1.0 THEN
  385.     ? "     **OOPS!** significance level >= 1.0"
  386. ELSE
  387.     ? "     significance level p ="prob 
  388.     IF nzeros=0 THEN
  389.         ans$=ans$+nmant$
  390.     ELSE
  391.         FOR i=1 TO nzeros
  392.             ans$=ans$+"0"
  393.         NEXT i
  394.         ans$=ans$+nmant$
  395.     END IF
  396.     IF prob<=.9 THEN 
  397.         ? "                     or p < "ans$
  398.     ELSE
  399.         ? "                     or p < 1.0"
  400.     END IF
  401. END IF
  402.  
  403. 'after results display, wait for user entry
  404.  
  405. waituser:
  406. LOCATE 15,27,0 : ?"Press any key to continue"
  407. DO 
  408.     IF INKEY$<>"" THEN EXIT LOOP
  409.     SLEEP
  410. LOOP
  411.  
  412. continue flg%
  413. IF flg%=0 THEN
  414.     GOTO finish
  415. ELSE
  416.     ERASE DObs, DExd, DSumRow, DSumCol
  417.     GOTO start
  418. END IF
  419.  
  420. finish: WINDOW CLOSE 1
  421.     STOP
  422.  
  423.  
  424.  
  425.