Changeset 3598
 Timestamp:
 Mar 8, 2013, 3:22:11 AM (20 months ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

cpu/arm/olpc/nntouchscreen.fth
r3576 r3598 917 917 ; 918 918 919 \ Nonlinearity test 920 921 d# 2000 constant #ptsmax 922 923 #ptsmax /w* value /buf 924 0 value xbuf 925 0 value ybuf 926 0 value #pts 927 928 : allocbufs (  ) 929 /buf allocmem to xbuf 930 /buf allocmem to ybuf 931 0 to #pts 932 ; 933 934 : freebufs (  ) 935 xbuf /buf freemem 936 ybuf /buf freemem 937 0 to #pts 938 ; 939 940 : +w@ ( adr index  w ) wa+ w@ ; 941 : +w! ( w adr index  ) wa+ w! ; 942 943 : addpt ( w.x w.y  ) 944 #pts #ptsmax u< if 945 ybuf #pts +w! 946 xbuf #pts +w! 947 #pts 1+ to #pts 948 else 949 2drop 950 then 951 ; 952 953 : listpts (  ) 954 #pts 0 ?do 955 i . ." : " xbuf i +w@ . ybuf i +w@ . cr 956 loop 957 ; 958 959 : sumover ( buf size  sum ) 960 0 rot /w* bounds ?do ( sum ) 961 i w@ + ( sum' ) 962 /w +loop ( sum ) 963 ; 964 965 \ Maximum values, assuming maxx = 1200, maxy = 900, #pts = 2000 966 \ maxx2 = 1200 * 1200 = 1,440,000 967 \ maxxy = 1200 * 900 = 1,080,000 968 \ maxSx = 1200 * 2000 = 2,400,000 969 \ maxSy = 900 * 2000 = 1,800,000 970 \ maxSx2 = maxx2 * 2000 = 2,880,000,000 971 \ maxSxy = maxxy * 2000 = 2,160,000,000 972 973 \ The max value for the denominator Sx2  (Sx)2/n occurs when 974 \ half the samples are 0 and the other half are maxx 975 \ maxdenom = maxSx2 / 4 = 720,000,000 976 977 \ A similar argument applies to the numerator, except that it 978 \ can be either negative or positive. But its maximum absolute 979 \ value is of the same order of magnitude as maxdenom 980 981 \ calculate the sum over x^2 (a double int) 982 \ The maximum value is maxx * maxx * #pts 983 \ For maxx = 1200 and #pts = 2000, maxSx2 is 2,880,000,000 984 : sumx2 (  Sx2 ) 985 0 #pts 0 ?do ( Sx2 ) 986 xbuf i +w@ ( Sx2 x ) 987 dup u* + ( Sx2' ) 988 loop ( Sx2 ) 989 ; 990 991 \ calculate the sum over xy (a double int) 992 : sumxy (  Sxy ) 993 0 #pts 0 ?do ( S ) 994 xbuf i +w@ ( S x ) 995 ybuf i +w@ ( S x y ) 996 u* + ( S' ) 997 loop ( S ) 998 ; 999 1000 0 value sumx 1001 0 value sumy 1002 : linearleastsquares (  intercept num den ) 1003 xbuf #pts sumover to sumx 1004 ybuf #pts sumover to sumy 1005 1006 \ Slope numerator: SUM(xy)  (SUM(x)*SUM(y) / #pts) 1007 1008 \ Sx max is #pts * xmax 1009 \ Sy max is #pts * ymax 1010 \ (Sx * Sy)/#pts max is xmax * ymax * #pts 1011 sumx sumy #pts */ ( Sx*Sy/#pts ) 1012 sumxy swap  ( num ) 1013 1014 \ Slope denominator: SUM(x^2)  (SUM(x)^2 / #pts) 1015 sumx sumx #pts */ ( num Sx*Sx/#pts ) 1016 sumx2 swap  ( num den ) 1017 \ Avoid division by 0 1018 dup 0= if 1+ then ( num den ) 1019 1020 \ Calculate the intercept 1021 2dup sumx #pts / rot */ ( num den slope*Sx ) 1022 1023 sumy #pts / ( num den slope*Sx meany ) 1024 swap  rot ( intercept num den ) 1025 ; 1026 1027 : dopoint ( x y  ) 2dup addpt dot ; 1028 1029 \ draw line across screen from left to right 1030 : lineinx ( intercept num den  ) 1031 screenw 0 do ( intercept num den ) 1032 3dup i rot */ + ( intercept num den pointy ) 1033 dup 1 screenh within if ( intercept num den pointy ) 1034 i swap dot ( intercept num den ) 1035 else ( intercept num den pointy ) 1036 drop ( intercept num den ) 1037 then ( intercept num den ) 1038 loop ( intercept num den ) 1039 3drop ( ) 1040 ; 1041 \ draw line from top to bottom of screen 1042 : lineiny ( intercept num den  ) 1043 swap rot ( den num intercept ) 1044 screenh 0 do ( den num intercept ) 1045 3dup i swap  ( den num intercept den num yb ) 1046 rot */ ( den num intercept pointx ) 1047 dup 1 screenw within if ( den num intercept pointy ) 1048 i dot ( den num intercept ) 1049 else ( den num intercept pointy ) 1050 drop ( den num intercept ) 1051 then ( den num intercept ) 1052 loop ( den num intercept ) 1053 3drop ( ) 1054 ; 1055 : drawline ( intercept num den color  ) 1056 pixcolor ! ( intercept num den ) 1057 2 pick abs 2 pick abs > if lineiny else lineinx then 1058 ; 1059 1060 0 value err2 1061 : nonlinearity ( intercept num den  meansqnonlinearity ) 1062 0 to err2 ( intercept num den ) 1063 #pts 0 ?do ( intercept num den ) 1064 3dup ( intercept num den intercept num den ) 1065 xbuf i +w@ ( intercept num den intercept num den x ) 1066 rot */ + ( intercept num den predictedy ) 1067 ybuf i +w@  ( intercept num den error ) 1068 dup * ( intercept num den error^2 ) 1069 err2 + to err2 ( intercept num den ) 1070 loop ( intercept num den ) 1071 3drop ( ) 1072 err2 #pts / ( Serror2/#pts ) 1073 ; 1074 1075 \ TODO: 1076 \ 1) Message and retry if slope and intercept not approximately correct 1077 \ slope can be checked with 1078 \ ( num den ) h# 10000 rot */ LOW HIGH within 1079 \ ( expected slope is negative , so LOW and HIGH are negative ) 1080 \ 2) Establish threshold for nonlinearity and fail if exceeded 1081 \ 3) Perhaps integrate the nonlinearity test with the targets test? 919 1082 920 1083 : scribble 921 ev( ['] dot ev )ev 922 ; 1084 allocbufs 1085 ev( 1086 0 d# 27 atxy ." Follow the line. Type a key to exit" cr 1087 screenh 6  screenh negate screenw blue drawline 1088 ['] dopoint ev 1089 linearleastsquares ( intercept num den ) 1090 3dup red drawline ( intercept num den ) 1091 ." Nonlinearity: " nonlinearity .d cr 1092 d# 5000 ms 1093 )ev 1094 freebufs 1095 ; 1096 1097 \ : scribble 1098 \ ev( ['] dot ev )ev 1099 \ ; 923 1100 924 1101
Note: See TracChangeset
for help on using the changeset viewer.