diff --git a/applications/lazstats/data/autocorr.laz b/applications/lazstats/data/autocorr.laz new file mode 100644 index 000000000..68c1e996b --- /dev/null +++ b/applications/lazstats/data/autocorr.laz @@ -0,0 +1,413 @@ +201 +1 +VAR +VARIABLE 1 +5 +F +3 +99999 +L +Case 0 +VAR +Case 1 +5.310 +Case 2 +5.267 +Case 3 +5.936 +Case 4 +6.032 +Case 5 +6.048 +Case 6 +6.188 +Case 7 +6.038 +Case 8 +6.344 +Case 9 +6.176 +Case 10 +5.780 +Case 11 +5.678 +Case 12 +5.843 +Case 13 +5.342 +Case 14 +5.373 +Case 15 +4.798 +Case 16 +4.622 +Case 17 +4.634 +Case 18 +4.267 +Case 19 +4.504 +Case 20 +4.424 +Case 21 +4.452 +Case 22 +4.597 +Case 23 +4.353 +Case 24 +4.671 +Case 25 +4.908 +Case 26 +5.095 +Case 27 +5.257 +Case 28 +5.558 +Case 29 +6.128 +Case 30 +6.144 +Case 31 +6.409 +Case 32 +6.453 +Case 33 +6.309 +Case 34 +5.981 +Case 35 +6.042 +Case 36 +5.932 +Case 37 +5.751 +Case 38 +5.196 +Case 39 +5.145 +Case 40 +4.971 +Case 41 +4.605 +Case 42 +4.381 +Case 43 +4.451 +Case 44 +4.055 +Case 45 +4.309 +Case 46 +4.369 +Case 47 +4.504 +Case 48 +4.506 +Case 49 +4.559 +Case 50 +5.049 +Case 51 +5.398 +Case 52 +5.608 +Case 53 +5.800 +Case 54 +5.969 +Case 55 +5.867 +Case 56 +6.154 +Case 57 +6.482 +Case 58 +6.322 +Case 59 +6.040 +Case 60 +5.911 +Case 61 +6.066 +Case 62 +5.908 +Case 63 +5.582 +Case 64 +4.985 +Case 65 +5.156 +Case 66 +4.549 +Case 67 +4.322 +Case 68 +4.140 +Case 69 +4.434 +Case 70 +4.338 +Case 71 +4.221 +Case 72 +4.578 +Case 73 +4.251 +Case 74 +4.788 +Case 75 +5.083 +Case 76 +5.303 +Case 77 +5.276 +Case 78 +5.581 +Case 79 +5.848 +Case 80 +5.998 +Case 81 +6.140 +Case 82 +5.992 +Case 83 +6.409 +Case 84 +6.418 +Case 85 +6.141 +Case 86 +5.908 +Case 87 +5.765 +Case 88 +5.354 +Case 89 +5.033 +Case 90 +5.083 +Case 91 +4.878 +Case 92 +4.467 +Case 93 +4.612 +Case 94 +4.471 +Case 95 +4.242 +Case 96 +4.446 +Case 97 +4.431 +Case 98 +4.566 +Case 99 +4.520 +Case 100 +4.705 +Case 101 +4.914 +Case 102 +5.541 +Case 103 +5.745 +Case 104 +5.667 +Case 105 +5.834 +Case 106 +6.185 +Case 107 +6.406 +Case 108 +6.450 +Case 109 +6.122 +Case 110 +5.892 +Case 111 +5.977 +Case 112 +5.928 +Case 113 +5.383 +Case 114 +5.450 +Case 115 +4.973 +Case 116 +4.682 +Case 117 +4.536 +Case 118 +4.454 +Case 119 +4.121 +Case 120 +4.398 +Case 121 +4.503 +Case 122 +4.348 +Case 123 +4.337 +Case 124 +4.801 +Case 125 +4.817 +Case 126 +5.178 +Case 127 +5.490 +Case 128 +5.407 +Case 129 +5.738 +Case 130 +6.070 +Case 131 +5.940 +Case 132 +6.188 +Case 133 +6.025 +Case 134 +6.315 +Case 135 +5.917 +Case 136 +6.080 +Case 137 +6.022 +Case 138 +5.508 +Case 139 +5.186 +Case 140 +5.293 +Case 141 +4.847 +Case 142 +4.838 +Case 143 +4.535 +Case 144 +4.166 +Case 145 +4.372 +Case 146 +4.137 +Case 147 +4.353 +Case 148 +4.280 +Case 149 +4.777 +Case 150 +5.013 +Case 151 +4.952 +Case 152 +5.371 +Case 153 +5.794 +Case 154 +5.607 +Case 155 +5.792 +Case 156 +5.889 +Case 157 +6.159 +Case 158 +6.239 +Case 159 +6.460 +Case 160 +6.363 +Case 161 +5.937 +Case 162 +5.828 +Case 163 +5.520 +Case 164 +5.447 +Case 165 +5.154 +Case 166 +4.690 +Case 167 +4.484 +Case 168 +4.556 +Case 169 +4.183 +Case 170 +4.373 +Case 171 +4.363 +Case 172 +4.084 +Case 173 +4.563 +Case 174 +4.707 +Case 175 +4.892 +Case 176 +5.194 +Case 177 +5.477 +Case 178 +5.350 +Case 179 +5.683 +Case 180 +6.034 +Case 181 +6.036 +Case 182 +6.386 +Case 183 +6.436 +Case 184 +6.004 +Case 185 +5.921 +Case 186 +6.016 +Case 187 +5.762 +Case 188 +5.481 +Case 189 +5.496 +Case 190 +5.102 +Case 191 +4.648 +Case 192 +4.600 +Case 193 +4.444 +Case 194 +4.411 +Case 195 +4.097 +Case 196 +4.492 +Case 197 +4.300 +Case 198 +4.326 +Case 199 +4.400 +Case 200 +4.879 +Case 201 +4.868 diff --git a/applications/lazstats/data/polydif.laz b/applications/lazstats/data/polydif.laz new file mode 100644 index 000000000..aad4f5286 --- /dev/null +++ b/applications/lazstats/data/polydif.laz @@ -0,0 +1,2535 @@ +500 +4 +Group +VARIABLE 1 +4 +F +2 +99999 +L +Item1 +VARIABLE 2 +4 +F +2 +99999 +L +Item2 +VARIABLE 3 +4 +F +2 +99999 +L +Item3 +VARIABLE 4 +4 +F +2 +99999 +L +Case 0 +Group +Item1 +Item2 +Item3 +Case 1 +2.00 +5.00 +1.00 +5.00 +Case 2 +2.00 +3.00 +4.00 +2.00 +Case 3 +1.00 +2.00 +1.00 +4.00 +Case 4 +1.00 +5.00 +5.00 +4.00 +Case 5 +1.00 +4.00 +1.00 +2.00 +Case 6 +2.00 +2.00 +3.00 +3.00 +Case 7 +1.00 +4.00 +3.00 +3.00 +Case 8 +2.00 +5.00 +4.00 +3.00 +Case 9 +2.00 +1.00 +1.00 +3.00 +Case 10 +1.00 +5.00 +2.00 +4.00 +Case 11 +1.00 +5.00 +4.00 +5.00 +Case 12 +1.00 +2.00 +1.00 +5.00 +Case 13 +1.00 +5.00 +4.00 +5.00 +Case 14 +1.00 +1.00 +2.00 +1.00 +Case 15 +1.00 +2.00 +4.00 +2.00 +Case 16 +1.00 +4.00 +3.00 +4.00 +Case 17 +2.00 +2.00 +3.00 +4.00 +Case 18 +2.00 +4.00 +1.00 +5.00 +Case 19 +1.00 +3.00 +2.00 +5.00 +Case 20 +2.00 +1.00 +1.00 +1.00 +Case 21 +1.00 +1.00 +2.00 +5.00 +Case 22 +2.00 +5.00 +3.00 +1.00 +Case 23 +2.00 +2.00 +1.00 +5.00 +Case 24 +2.00 +5.00 +5.00 +2.00 +Case 25 +1.00 +1.00 +5.00 +4.00 +Case 26 +2.00 +4.00 +2.00 +3.00 +Case 27 +1.00 +4.00 +2.00 +4.00 +Case 28 +1.00 +3.00 +3.00 +2.00 +Case 29 +2.00 +1.00 +5.00 +5.00 +Case 30 +1.00 +4.00 +2.00 +3.00 +Case 31 +1.00 +5.00 +5.00 +1.00 +Case 32 +2.00 +5.00 +1.00 +1.00 +Case 33 +2.00 +2.00 +3.00 +2.00 +Case 34 +2.00 +2.00 +3.00 +1.00 +Case 35 +1.00 +1.00 +2.00 +5.00 +Case 36 +1.00 +4.00 +3.00 +1.00 +Case 37 +1.00 +1.00 +5.00 +2.00 +Case 38 +2.00 +5.00 +3.00 +1.00 +Case 39 +1.00 +2.00 +5.00 +4.00 +Case 40 +1.00 +1.00 +2.00 +2.00 +Case 41 +1.00 +2.00 +1.00 +1.00 +Case 42 +2.00 +2.00 +5.00 +4.00 +Case 43 +2.00 +2.00 +4.00 +5.00 +Case 44 +1.00 +4.00 +1.00 +4.00 +Case 45 +1.00 +3.00 +5.00 +4.00 +Case 46 +1.00 +1.00 +3.00 +4.00 +Case 47 +1.00 +4.00 +4.00 +2.00 +Case 48 +2.00 +1.00 +2.00 +2.00 +Case 49 +2.00 +5.00 +2.00 +2.00 +Case 50 +2.00 +1.00 +4.00 +2.00 +Case 51 +2.00 +4.00 +2.00 +1.00 +Case 52 +1.00 +2.00 +3.00 +2.00 +Case 53 +1.00 +4.00 +2.00 +2.00 +Case 54 +2.00 +3.00 +1.00 +3.00 +Case 55 +1.00 +4.00 +5.00 +1.00 +Case 56 +2.00 +3.00 +3.00 +5.00 +Case 57 +1.00 +3.00 +3.00 +2.00 +Case 58 +2.00 +1.00 +1.00 +2.00 +Case 59 +1.00 +5.00 +5.00 +1.00 +Case 60 +2.00 +3.00 +5.00 +1.00 +Case 61 +2.00 +2.00 +2.00 +1.00 +Case 62 +1.00 +4.00 +2.00 +2.00 +Case 63 +1.00 +1.00 +1.00 +2.00 +Case 64 +1.00 +2.00 +1.00 +3.00 +Case 65 +1.00 +4.00 +2.00 +4.00 +Case 66 +1.00 +2.00 +5.00 +3.00 +Case 67 +2.00 +2.00 +1.00 +2.00 +Case 68 +1.00 +4.00 +4.00 +4.00 +Case 69 +2.00 +3.00 +4.00 +3.00 +Case 70 +1.00 +2.00 +2.00 +4.00 +Case 71 +2.00 +1.00 +1.00 +4.00 +Case 72 +1.00 +2.00 +2.00 +5.00 +Case 73 +2.00 +4.00 +2.00 +2.00 +Case 74 +1.00 +1.00 +1.00 +5.00 +Case 75 +2.00 +1.00 +3.00 +2.00 +Case 76 +1.00 +5.00 +1.00 +5.00 +Case 77 +2.00 +4.00 +2.00 +2.00 +Case 78 +1.00 +5.00 +1.00 +4.00 +Case 79 +1.00 +2.00 +5.00 +1.00 +Case 80 +2.00 +4.00 +5.00 +1.00 +Case 81 +2.00 +3.00 +5.00 +3.00 +Case 82 +1.00 +4.00 +4.00 +4.00 +Case 83 +2.00 +1.00 +5.00 +5.00 +Case 84 +1.00 +4.00 +4.00 +3.00 +Case 85 +1.00 +3.00 +4.00 +3.00 +Case 86 +1.00 +3.00 +2.00 +1.00 +Case 87 +1.00 +4.00 +1.00 +3.00 +Case 88 +2.00 +5.00 +2.00 +3.00 +Case 89 +1.00 +3.00 +5.00 +4.00 +Case 90 +2.00 +2.00 +3.00 +4.00 +Case 91 +1.00 +1.00 +1.00 +5.00 +Case 92 +2.00 +4.00 +2.00 +1.00 +Case 93 +1.00 +3.00 +1.00 +4.00 +Case 94 +2.00 +1.00 +1.00 +3.00 +Case 95 +2.00 +1.00 +4.00 +4.00 +Case 96 +2.00 +5.00 +3.00 +2.00 +Case 97 +1.00 +5.00 +5.00 +2.00 +Case 98 +1.00 +3.00 +2.00 +3.00 +Case 99 +1.00 +2.00 +1.00 +5.00 +Case 100 +1.00 +4.00 +3.00 +1.00 +Case 101 +1.00 +3.00 +1.00 +3.00 +Case 102 +2.00 +1.00 +1.00 +2.00 +Case 103 +2.00 +3.00 +2.00 +1.00 +Case 104 +1.00 +3.00 +1.00 +5.00 +Case 105 +1.00 +3.00 +3.00 +3.00 +Case 106 +1.00 +1.00 +5.00 +4.00 +Case 107 +2.00 +3.00 +3.00 +5.00 +Case 108 +1.00 +2.00 +3.00 +3.00 +Case 109 +1.00 +2.00 +2.00 +3.00 +Case 110 +2.00 +1.00 +5.00 +3.00 +Case 111 +1.00 +3.00 +3.00 +3.00 +Case 112 +2.00 +2.00 +1.00 +2.00 +Case 113 +1.00 +2.00 +4.00 +5.00 +Case 114 +2.00 +3.00 +2.00 +2.00 +Case 115 +2.00 +1.00 +1.00 +5.00 +Case 116 +2.00 +5.00 +3.00 +1.00 +Case 117 +1.00 +4.00 +3.00 +2.00 +Case 118 +1.00 +1.00 +5.00 +5.00 +Case 119 +1.00 +2.00 +5.00 +1.00 +Case 120 +2.00 +1.00 +5.00 +1.00 +Case 121 +1.00 +4.00 +1.00 +1.00 +Case 122 +1.00 +3.00 +1.00 +3.00 +Case 123 +1.00 +1.00 +1.00 +1.00 +Case 124 +2.00 +4.00 +1.00 +3.00 +Case 125 +2.00 +4.00 +3.00 +1.00 +Case 126 +1.00 +4.00 +1.00 +3.00 +Case 127 +2.00 +1.00 +4.00 +3.00 +Case 128 +2.00 +4.00 +5.00 +4.00 +Case 129 +2.00 +1.00 +5.00 +4.00 +Case 130 +2.00 +2.00 +3.00 +2.00 +Case 131 +1.00 +3.00 +2.00 +1.00 +Case 132 +2.00 +1.00 +2.00 +1.00 +Case 133 +1.00 +3.00 +5.00 +2.00 +Case 134 +1.00 +3.00 +3.00 +1.00 +Case 135 +2.00 +5.00 +1.00 +5.00 +Case 136 +2.00 +1.00 +4.00 +5.00 +Case 137 +2.00 +1.00 +3.00 +2.00 +Case 138 +1.00 +2.00 +5.00 +1.00 +Case 139 +1.00 +2.00 +2.00 +3.00 +Case 140 +2.00 +5.00 +2.00 +1.00 +Case 141 +2.00 +2.00 +5.00 +2.00 +Case 142 +1.00 +1.00 +4.00 +3.00 +Case 143 +2.00 +4.00 +1.00 +5.00 +Case 144 +1.00 +4.00 +2.00 +2.00 +Case 145 +1.00 +1.00 +3.00 +4.00 +Case 146 +2.00 +3.00 +1.00 +3.00 +Case 147 +1.00 +4.00 +2.00 +4.00 +Case 148 +1.00 +5.00 +1.00 +2.00 +Case 149 +1.00 +2.00 +2.00 +3.00 +Case 150 +1.00 +5.00 +1.00 +3.00 +Case 151 +1.00 +3.00 +2.00 +1.00 +Case 152 +2.00 +1.00 +2.00 +1.00 +Case 153 +2.00 +1.00 +1.00 +5.00 +Case 154 +1.00 +4.00 +1.00 +1.00 +Case 155 +2.00 +5.00 +3.00 +2.00 +Case 156 +1.00 +2.00 +4.00 +2.00 +Case 157 +2.00 +1.00 +5.00 +4.00 +Case 158 +1.00 +1.00 +2.00 +4.00 +Case 159 +1.00 +2.00 +1.00 +4.00 +Case 160 +1.00 +4.00 +1.00 +2.00 +Case 161 +1.00 +4.00 +5.00 +4.00 +Case 162 +1.00 +2.00 +1.00 +1.00 +Case 163 +1.00 +1.00 +1.00 +4.00 +Case 164 +2.00 +1.00 +3.00 +4.00 +Case 165 +1.00 +4.00 +4.00 +2.00 +Case 166 +1.00 +1.00 +4.00 +5.00 +Case 167 +1.00 +5.00 +5.00 +5.00 +Case 168 +2.00 +4.00 +2.00 +2.00 +Case 169 +1.00 +5.00 +2.00 +2.00 +Case 170 +1.00 +2.00 +1.00 +2.00 +Case 171 +2.00 +2.00 +3.00 +2.00 +Case 172 +2.00 +3.00 +2.00 +5.00 +Case 173 +2.00 +4.00 +3.00 +1.00 +Case 174 +1.00 +2.00 +1.00 +3.00 +Case 175 +1.00 +4.00 +2.00 +1.00 +Case 176 +2.00 +2.00 +2.00 +4.00 +Case 177 +1.00 +3.00 +3.00 +1.00 +Case 178 +1.00 +3.00 +1.00 +2.00 +Case 179 +1.00 +5.00 +2.00 +5.00 +Case 180 +1.00 +2.00 +4.00 +5.00 +Case 181 +1.00 +2.00 +2.00 +2.00 +Case 182 +2.00 +5.00 +5.00 +1.00 +Case 183 +1.00 +3.00 +2.00 +5.00 +Case 184 +2.00 +2.00 +3.00 +1.00 +Case 185 +1.00 +3.00 +2.00 +1.00 +Case 186 +1.00 +5.00 +3.00 +1.00 +Case 187 +1.00 +2.00 +1.00 +4.00 +Case 188 +2.00 +1.00 +1.00 +5.00 +Case 189 +2.00 +5.00 +3.00 +4.00 +Case 190 +2.00 +2.00 +4.00 +5.00 +Case 191 +1.00 +5.00 +2.00 +4.00 +Case 192 +1.00 +5.00 +5.00 +4.00 +Case 193 +1.00 +2.00 +3.00 +4.00 +Case 194 +1.00 +3.00 +3.00 +4.00 +Case 195 +1.00 +4.00 +4.00 +5.00 +Case 196 +1.00 +2.00 +5.00 +3.00 +Case 197 +1.00 +5.00 +2.00 +5.00 +Case 198 +2.00 +4.00 +2.00 +5.00 +Case 199 +2.00 +2.00 +1.00 +2.00 +Case 200 +2.00 +5.00 +2.00 +3.00 +Case 201 +2.00 +3.00 +5.00 +1.00 +Case 202 +1.00 +5.00 +4.00 +1.00 +Case 203 +1.00 +1.00 +2.00 +2.00 +Case 204 +1.00 +4.00 +1.00 +5.00 +Case 205 +1.00 +5.00 +3.00 +5.00 +Case 206 +2.00 +1.00 +2.00 +2.00 +Case 207 +2.00 +3.00 +5.00 +5.00 +Case 208 +1.00 +1.00 +3.00 +4.00 +Case 209 +2.00 +4.00 +5.00 +2.00 +Case 210 +1.00 +2.00 +3.00 +3.00 +Case 211 +2.00 +5.00 +4.00 +3.00 +Case 212 +1.00 +4.00 +3.00 +2.00 +Case 213 +2.00 +1.00 +5.00 +5.00 +Case 214 +1.00 +1.00 +3.00 +5.00 +Case 215 +2.00 +5.00 +1.00 +3.00 +Case 216 +1.00 +3.00 +3.00 +1.00 +Case 217 +2.00 +2.00 +5.00 +2.00 +Case 218 +1.00 +5.00 +2.00 +5.00 +Case 219 +2.00 +4.00 +3.00 +2.00 +Case 220 +2.00 +3.00 +5.00 +1.00 +Case 221 +2.00 +1.00 +2.00 +5.00 +Case 222 +1.00 +3.00 +4.00 +1.00 +Case 223 +1.00 +1.00 +3.00 +3.00 +Case 224 +2.00 +5.00 +3.00 +4.00 +Case 225 +1.00 +3.00 +3.00 +5.00 +Case 226 +1.00 +3.00 +4.00 +4.00 +Case 227 +2.00 +2.00 +1.00 +5.00 +Case 228 +2.00 +4.00 +4.00 +3.00 +Case 229 +2.00 +1.00 +2.00 +2.00 +Case 230 +1.00 +3.00 +1.00 +5.00 +Case 231 +1.00 +2.00 +2.00 +1.00 +Case 232 +1.00 +3.00 +4.00 +5.00 +Case 233 +2.00 +2.00 +2.00 +1.00 +Case 234 +2.00 +2.00 +2.00 +2.00 +Case 235 +2.00 +4.00 +2.00 +5.00 +Case 236 +1.00 +4.00 +1.00 +4.00 +Case 237 +2.00 +3.00 +3.00 +5.00 +Case 238 +1.00 +1.00 +4.00 +1.00 +Case 239 +2.00 +1.00 +1.00 +5.00 +Case 240 +2.00 +3.00 +1.00 +5.00 +Case 241 +1.00 +1.00 +1.00 +3.00 +Case 242 +1.00 +4.00 +3.00 +3.00 +Case 243 +2.00 +4.00 +1.00 +4.00 +Case 244 +1.00 +2.00 +1.00 +2.00 +Case 245 +1.00 +1.00 +5.00 +5.00 +Case 246 +1.00 +4.00 +4.00 +2.00 +Case 247 +1.00 +5.00 +2.00 +4.00 +Case 248 +2.00 +2.00 +1.00 +3.00 +Case 249 +1.00 +1.00 +2.00 +3.00 +Case 250 +1.00 +2.00 +4.00 +5.00 +Case 251 +2.00 +1.00 +2.00 +4.00 +Case 252 +1.00 +5.00 +2.00 +5.00 +Case 253 +1.00 +4.00 +4.00 +4.00 +Case 254 +2.00 +3.00 +5.00 +1.00 +Case 255 +2.00 +2.00 +3.00 +5.00 +Case 256 +2.00 +5.00 +1.00 +5.00 +Case 257 +1.00 +1.00 +3.00 +3.00 +Case 258 +2.00 +1.00 +2.00 +4.00 +Case 259 +2.00 +2.00 +1.00 +4.00 +Case 260 +1.00 +4.00 +2.00 +2.00 +Case 261 +2.00 +4.00 +2.00 +1.00 +Case 262 +1.00 +5.00 +1.00 +1.00 +Case 263 +2.00 +1.00 +5.00 +4.00 +Case 264 +1.00 +1.00 +5.00 +3.00 +Case 265 +2.00 +1.00 +3.00 +4.00 +Case 266 +1.00 +2.00 +2.00 +1.00 +Case 267 +2.00 +2.00 +5.00 +5.00 +Case 268 +2.00 +4.00 +3.00 +3.00 +Case 269 +2.00 +4.00 +1.00 +3.00 +Case 270 +2.00 +1.00 +1.00 +5.00 +Case 271 +2.00 +2.00 +5.00 +2.00 +Case 272 +2.00 +3.00 +2.00 +2.00 +Case 273 +2.00 +1.00 +1.00 +3.00 +Case 274 +2.00 +1.00 +3.00 +5.00 +Case 275 +2.00 +1.00 +1.00 +3.00 +Case 276 +2.00 +3.00 +5.00 +3.00 +Case 277 +2.00 +5.00 +2.00 +4.00 +Case 278 +1.00 +5.00 +5.00 +3.00 +Case 279 +1.00 +1.00 +2.00 +5.00 +Case 280 +2.00 +2.00 +5.00 +3.00 +Case 281 +1.00 +4.00 +4.00 +4.00 +Case 282 +1.00 +4.00 +1.00 +1.00 +Case 283 +2.00 +5.00 +2.00 +1.00 +Case 284 +1.00 +5.00 +1.00 +4.00 +Case 285 +2.00 +2.00 +4.00 +2.00 +Case 286 +1.00 +5.00 +4.00 +2.00 +Case 287 +1.00 +2.00 +1.00 +5.00 +Case 288 +1.00 +1.00 +5.00 +3.00 +Case 289 +1.00 +5.00 +3.00 +2.00 +Case 290 +2.00 +3.00 +1.00 +4.00 +Case 291 +2.00 +5.00 +1.00 +1.00 +Case 292 +1.00 +2.00 +2.00 +5.00 +Case 293 +2.00 +3.00 +2.00 +4.00 +Case 294 +1.00 +4.00 +4.00 +4.00 +Case 295 +1.00 +1.00 +2.00 +2.00 +Case 296 +1.00 +2.00 +1.00 +3.00 +Case 297 +1.00 +2.00 +1.00 +1.00 +Case 298 +2.00 +4.00 +5.00 +1.00 +Case 299 +2.00 +5.00 +1.00 +2.00 +Case 300 +1.00 +2.00 +5.00 +5.00 +Case 301 +1.00 +3.00 +4.00 +5.00 +Case 302 +1.00 +5.00 +1.00 +3.00 +Case 303 +2.00 +1.00 +5.00 +4.00 +Case 304 +1.00 +4.00 +1.00 +1.00 +Case 305 +1.00 +3.00 +4.00 +5.00 +Case 306 +1.00 +1.00 +4.00 +3.00 +Case 307 +1.00 +1.00 +1.00 +4.00 +Case 308 +1.00 +1.00 +2.00 +4.00 +Case 309 +1.00 +3.00 +4.00 +4.00 +Case 310 +2.00 +4.00 +5.00 +5.00 +Case 311 +1.00 +5.00 +1.00 +3.00 +Case 312 +1.00 +1.00 +1.00 +5.00 +Case 313 +2.00 +4.00 +5.00 +2.00 +Case 314 +1.00 +3.00 +3.00 +3.00 +Case 315 +2.00 +4.00 +4.00 +3.00 +Case 316 +1.00 +3.00 +5.00 +5.00 +Case 317 +1.00 +2.00 +3.00 +4.00 +Case 318 +1.00 +1.00 +1.00 +3.00 +Case 319 +2.00 +1.00 +3.00 +2.00 +Case 320 +1.00 +1.00 +1.00 +4.00 +Case 321 +1.00 +3.00 +3.00 +3.00 +Case 322 +2.00 +4.00 +2.00 +5.00 +Case 323 +2.00 +5.00 +5.00 +4.00 +Case 324 +1.00 +5.00 +3.00 +3.00 +Case 325 +1.00 +2.00 +4.00 +5.00 +Case 326 +2.00 +4.00 +5.00 +4.00 +Case 327 +2.00 +5.00 +3.00 +1.00 +Case 328 +1.00 +4.00 +4.00 +4.00 +Case 329 +1.00 +2.00 +5.00 +5.00 +Case 330 +2.00 +2.00 +1.00 +4.00 +Case 331 +2.00 +5.00 +3.00 +4.00 +Case 332 +2.00 +2.00 +1.00 +3.00 +Case 333 +1.00 +1.00 +1.00 +2.00 +Case 334 +2.00 +3.00 +4.00 +2.00 +Case 335 +1.00 +4.00 +5.00 +4.00 +Case 336 +2.00 +4.00 +5.00 +1.00 +Case 337 +1.00 +4.00 +1.00 +5.00 +Case 338 +2.00 +1.00 +3.00 +2.00 +Case 339 +2.00 +3.00 +2.00 +3.00 +Case 340 +2.00 +3.00 +2.00 +2.00 +Case 341 +2.00 +5.00 +3.00 +3.00 +Case 342 +2.00 +1.00 +3.00 +1.00 +Case 343 +1.00 +5.00 +3.00 +2.00 +Case 344 +1.00 +4.00 +2.00 +4.00 +Case 345 +2.00 +1.00 +2.00 +1.00 +Case 346 +1.00 +3.00 +1.00 +3.00 +Case 347 +1.00 +2.00 +1.00 +3.00 +Case 348 +2.00 +1.00 +4.00 +5.00 +Case 349 +1.00 +1.00 +5.00 +1.00 +Case 350 +1.00 +4.00 +1.00 +5.00 +Case 351 +2.00 +4.00 +5.00 +4.00 +Case 352 +1.00 +5.00 +1.00 +5.00 +Case 353 +2.00 +5.00 +4.00 +1.00 +Case 354 +2.00 +2.00 +3.00 +4.00 +Case 355 +2.00 +4.00 +2.00 +1.00 +Case 356 +2.00 +4.00 +2.00 +1.00 +Case 357 +1.00 +4.00 +1.00 +3.00 +Case 358 +2.00 +4.00 +3.00 +2.00 +Case 359 +1.00 +4.00 +1.00 +4.00 +Case 360 +1.00 +2.00 +5.00 +5.00 +Case 361 +2.00 +3.00 +4.00 +1.00 +Case 362 +2.00 +4.00 +1.00 +2.00 +Case 363 +1.00 +4.00 +5.00 +4.00 +Case 364 +2.00 +1.00 +3.00 +4.00 +Case 365 +1.00 +5.00 +3.00 +2.00 +Case 366 +2.00 +2.00 +5.00 +5.00 +Case 367 +1.00 +5.00 +4.00 +1.00 +Case 368 +2.00 +4.00 +5.00 +3.00 +Case 369 +2.00 +4.00 +1.00 +2.00 +Case 370 +2.00 +1.00 +3.00 +4.00 +Case 371 +1.00 +1.00 +4.00 +4.00 +Case 372 +1.00 +1.00 +3.00 +2.00 +Case 373 +1.00 +4.00 +2.00 +4.00 +Case 374 +1.00 +2.00 +5.00 +1.00 +Case 375 +2.00 +2.00 +5.00 +1.00 +Case 376 +1.00 +2.00 +2.00 +4.00 +Case 377 +2.00 +4.00 +5.00 +1.00 +Case 378 +2.00 +3.00 +4.00 +3.00 +Case 379 +1.00 +4.00 +1.00 +1.00 +Case 380 +1.00 +2.00 +5.00 +3.00 +Case 381 +1.00 +1.00 +1.00 +1.00 +Case 382 +1.00 +2.00 +1.00 +2.00 +Case 383 +2.00 +3.00 +4.00 +4.00 +Case 384 +2.00 +5.00 +4.00 +5.00 +Case 385 +1.00 +2.00 +5.00 +5.00 +Case 386 +1.00 +5.00 +3.00 +5.00 +Case 387 +1.00 +2.00 +2.00 +3.00 +Case 388 +1.00 +4.00 +4.00 +3.00 +Case 389 +1.00 +1.00 +3.00 +5.00 +Case 390 +2.00 +1.00 +4.00 +2.00 +Case 391 +1.00 +1.00 +2.00 +4.00 +Case 392 +1.00 +3.00 +1.00 +1.00 +Case 393 +1.00 +1.00 +5.00 +1.00 +Case 394 +1.00 +1.00 +4.00 +4.00 +Case 395 +1.00 +4.00 +5.00 +2.00 +Case 396 +1.00 +5.00 +2.00 +4.00 +Case 397 +1.00 +5.00 +3.00 +1.00 +Case 398 +2.00 +3.00 +1.00 +5.00 +Case 399 +2.00 +1.00 +2.00 +2.00 +Case 400 +1.00 +5.00 +3.00 +3.00 +Case 401 +2.00 +5.00 +2.00 +2.00 +Case 402 +2.00 +2.00 +2.00 +3.00 +Case 403 +1.00 +4.00 +5.00 +2.00 +Case 404 +2.00 +2.00 +5.00 +4.00 +Case 405 +2.00 +3.00 +5.00 +3.00 +Case 406 +2.00 +5.00 +1.00 +2.00 +Case 407 +1.00 +2.00 +5.00 +3.00 +Case 408 +2.00 +2.00 +3.00 +3.00 +Case 409 +1.00 +4.00 +5.00 +3.00 +Case 410 +1.00 +5.00 +3.00 +5.00 +Case 411 +2.00 +4.00 +4.00 +4.00 +Case 412 +1.00 +3.00 +5.00 +3.00 +Case 413 +1.00 +1.00 +5.00 +4.00 +Case 414 +2.00 +1.00 +5.00 +5.00 +Case 415 +1.00 +1.00 +4.00 +1.00 +Case 416 +2.00 +5.00 +4.00 +5.00 +Case 417 +1.00 +4.00 +4.00 +4.00 +Case 418 +1.00 +2.00 +1.00 +4.00 +Case 419 +2.00 +3.00 +4.00 +1.00 +Case 420 +1.00 +1.00 +5.00 +1.00 +Case 421 +2.00 +5.00 +1.00 +1.00 +Case 422 +1.00 +4.00 +3.00 +2.00 +Case 423 +2.00 +4.00 +1.00 +3.00 +Case 424 +2.00 +1.00 +3.00 +4.00 +Case 425 +2.00 +5.00 +5.00 +1.00 +Case 426 +1.00 +5.00 +4.00 +4.00 +Case 427 +2.00 +4.00 +3.00 +1.00 +Case 428 +2.00 +3.00 +3.00 +3.00 +Case 429 +2.00 +1.00 +5.00 +5.00 +Case 430 +1.00 +2.00 +2.00 +5.00 +Case 431 +1.00 +1.00 +5.00 +2.00 +Case 432 +1.00 +4.00 +5.00 +2.00 +Case 433 +2.00 +3.00 +3.00 +1.00 +Case 434 +2.00 +4.00 +1.00 +2.00 +Case 435 +2.00 +5.00 +4.00 +2.00 +Case 436 +1.00 +4.00 +2.00 +2.00 +Case 437 +1.00 +5.00 +4.00 +1.00 +Case 438 +1.00 +2.00 +3.00 +3.00 +Case 439 +1.00 +1.00 +4.00 +3.00 +Case 440 +2.00 +5.00 +3.00 +3.00 +Case 441 +1.00 +5.00 +3.00 +5.00 +Case 442 +2.00 +4.00 +5.00 +1.00 +Case 443 +2.00 +3.00 +4.00 +2.00 +Case 444 +1.00 +5.00 +4.00 +4.00 +Case 445 +2.00 +5.00 +3.00 +3.00 +Case 446 +1.00 +5.00 +4.00 +5.00 +Case 447 +2.00 +1.00 +4.00 +5.00 +Case 448 +1.00 +1.00 +1.00 +4.00 +Case 449 +1.00 +1.00 +5.00 +4.00 +Case 450 +1.00 +5.00 +4.00 +4.00 +Case 451 +2.00 +2.00 +1.00 +4.00 +Case 452 +2.00 +4.00 +3.00 +4.00 +Case 453 +2.00 +2.00 +4.00 +5.00 +Case 454 +2.00 +3.00 +4.00 +1.00 +Case 455 +2.00 +5.00 +3.00 +4.00 +Case 456 +1.00 +1.00 +3.00 +1.00 +Case 457 +2.00 +2.00 +2.00 +1.00 +Case 458 +2.00 +4.00 +5.00 +5.00 +Case 459 +1.00 +4.00 +3.00 +4.00 +Case 460 +2.00 +3.00 +4.00 +3.00 +Case 461 +1.00 +1.00 +5.00 +4.00 +Case 462 +1.00 +4.00 +1.00 +3.00 +Case 463 +1.00 +2.00 +2.00 +4.00 +Case 464 +2.00 +3.00 +2.00 +2.00 +Case 465 +2.00 +3.00 +2.00 +3.00 +Case 466 +2.00 +3.00 +1.00 +2.00 +Case 467 +1.00 +3.00 +1.00 +4.00 +Case 468 +1.00 +2.00 +1.00 +5.00 +Case 469 +1.00 +2.00 +1.00 +4.00 +Case 470 +2.00 +2.00 +2.00 +4.00 +Case 471 +1.00 +2.00 +4.00 +1.00 +Case 472 +1.00 +1.00 +1.00 +3.00 +Case 473 +1.00 +4.00 +3.00 +2.00 +Case 474 +2.00 +5.00 +4.00 +1.00 +Case 475 +1.00 +4.00 +1.00 +3.00 +Case 476 +1.00 +5.00 +1.00 +3.00 +Case 477 +1.00 +1.00 +5.00 +5.00 +Case 478 +2.00 +5.00 +4.00 +3.00 +Case 479 +1.00 +4.00 +4.00 +4.00 +Case 480 +2.00 +2.00 +2.00 +5.00 +Case 481 +1.00 +1.00 +2.00 +2.00 +Case 482 +1.00 +5.00 +4.00 +2.00 +Case 483 +1.00 +4.00 +3.00 +3.00 +Case 484 +1.00 +2.00 +4.00 +4.00 +Case 485 +2.00 +5.00 +2.00 +1.00 +Case 486 +2.00 +2.00 +3.00 +1.00 +Case 487 +2.00 +2.00 +4.00 +3.00 +Case 488 +2.00 +1.00 +4.00 +4.00 +Case 489 +1.00 +3.00 +5.00 +2.00 +Case 490 +2.00 +2.00 +5.00 +4.00 +Case 491 +1.00 +1.00 +2.00 +2.00 +Case 492 +2.00 +2.00 +3.00 +5.00 +Case 493 +2.00 +4.00 +4.00 +4.00 +Case 494 +2.00 +1.00 +2.00 +2.00 +Case 495 +1.00 +4.00 +5.00 +5.00 +Case 496 +2.00 +2.00 +5.00 +4.00 +Case 497 +2.00 +4.00 +5.00 +1.00 +Case 498 +2.00 +1.00 +2.00 +5.00 +Case 499 +2.00 +1.00 +3.00 +2.00 +Case 500 +1.00 +1.00 +5.00 +2.00 diff --git a/applications/lazstats/docs/HelpNDoc/LazStats.hnd b/applications/lazstats/docs/HelpNDoc/LazStats.hnd index 6cfb7936f..b6271f46e 100644 Binary files a/applications/lazstats/docs/HelpNDoc/LazStats.hnd and b/applications/lazstats/docs/HelpNDoc/LazStats.hnd differ diff --git a/applications/lazstats/source/forms/analysis/correlation/autocorunit.lfm b/applications/lazstats/source/forms/analysis/correlation/autocorunit.lfm index 212c036de..bff19404e 100644 --- a/applications/lazstats/source/forms/analysis/correlation/autocorunit.lfm +++ b/applications/lazstats/source/forms/analysis/correlation/autocorunit.lfm @@ -1,7 +1,7 @@ object AutoCorrFrm: TAutoCorrFrm Left = 456 Height = 459 - Top = 163 + Top = 145 Width = 684 AutoSize = True Caption = 'Autocorrelation' @@ -35,8 +35,10 @@ object AutoCorrFrm: TAutoCorrFrm Width = 99 BorderSpacing.Left = 16 Caption = 'A Grid Column' + Checked = True OnClick = ColBtnClick TabOrder = 0 + TabStop = True end object RowBtn: TRadioButton AnchorSideLeft.Control = ColBtn @@ -138,86 +140,67 @@ object AutoCorrFrm: TAutoCorrFrm end end object ResetBtn: TButton - AnchorSideRight.Control = CancelBtn + AnchorSideRight.Control = ComputeBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 387 + Left = 475 Height = 25 Top = 426 Width = 54 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Reset' OnClick = ResetBtnClick TabOrder = 5 end - object CancelBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 453 - Height = 25 - Top = 426 - Width = 62 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 12 - BorderSpacing.Top = 8 - BorderSpacing.Right = 12 - BorderSpacing.Bottom = 8 - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 6 - end object ComputeBtn: TButton - AnchorSideRight.Control = ReturnBtn + AnchorSideRight.Control = CloseBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 527 + Left = 537 Height = 25 Top = 426 Width = 76 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Compute' - ModalResult = 1 OnClick = ComputeBtnClick - TabOrder = 7 + TabOrder = 6 end - object ReturnBtn: TButton + object CloseBtn: TButton AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 615 + Left = 621 Height = 25 Top = 426 - Width = 61 + Width = 55 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - Caption = 'Return' - ModalResult = 1 - OnClick = ReturnBtnClick - TabOrder = 8 + Caption = 'Close' + ModalResult = 11 + OnClick = CloseBtnClick + TabOrder = 7 end object HelpBtn: TButton Tag = 104 AnchorSideRight.Control = ResetBtn AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 324 + Left = 416 Height = 25 Top = 426 Width = 51 @@ -225,7 +208,7 @@ object AutoCorrFrm: TAutoCorrFrm AutoSize = True BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Help' OnClick = HelpBtnClick @@ -235,7 +218,7 @@ object AutoCorrFrm: TAutoCorrFrm AnchorSideLeft.Control = Owner AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = ReturnBtn + AnchorSideBottom.Control = CloseBtn Left = 0 Height = 8 Top = 410 @@ -383,6 +366,7 @@ object AutoCorrFrm: TAutoCorrFrm BorderSpacing.Right = 8 Constraints.MinHeight = 220 ItemHeight = 0 + OnSelectionChange = VarListSelectionChange TabOrder = 0 end object InBtn: TBitBtn @@ -500,6 +484,7 @@ object AutoCorrFrm: TAutoCorrFrm Anchors = [akLeft, akRight, akBottom] BorderSpacing.Left = 8 BorderSpacing.Bottom = 12 + ReadOnly = True TabOrder = 3 Text = 'DepVarEdit' end @@ -659,31 +644,31 @@ object AutoCorrFrm: TAutoCorrFrm Left = 12 Height = 19 Top = 6 - Width = 142 - Caption = 'Correlogram' + Width = 148 + Caption = 'Plot correlogram' TabOrder = 0 end object StatsChk: TCheckBox Left = 12 Height = 19 Top = 27 - Width = 142 - Caption = 'Statistics' + Width = 148 + Caption = 'Print statistics' TabOrder = 1 end object RMatChk: TCheckBox Left = 12 Height = 19 Top = 48 - Width = 142 - Caption = 'Print correlation Mat.' + Width = 148 + Caption = 'Print correlation matrix' TabOrder = 2 end object PartialsChk: TCheckBox Left = 12 Height = 19 Top = 69 - Width = 142 + Width = 148 Caption = 'Partial autocorrelations' TabOrder = 3 end @@ -691,16 +676,16 @@ object AutoCorrFrm: TAutoCorrFrm Left = 12 Height = 19 Top = 90 - Width = 142 - Caption = 'Yule-Walker Coef.s' + Width = 148 + Caption = 'Yule-Walker coefficients' TabOrder = 4 end object ResidChk: TCheckBox Left = 12 Height = 19 Top = 111 - Width = 142 - Caption = 'Residual Plot' + Width = 148 + Caption = 'Residual plot' TabOrder = 5 end end diff --git a/applications/lazstats/source/forms/analysis/correlation/autocorunit.pas b/applications/lazstats/source/forms/analysis/correlation/autocorunit.pas index a5ed68349..e5e7d2d3b 100644 --- a/applications/lazstats/source/forms/analysis/correlation/autocorunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/autocorunit.pas @@ -1,3 +1,9 @@ +// File for testing: +// --- not found (the pdf docs mention "strikes.tab" - but this does not exist. +// -- created test file autocorr.laz + +// TODO: Crashes when multiple smoothing options are applied. + unit AutoCorUnit; {$mode objfpc}{$H+} @@ -8,7 +14,7 @@ uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, Buttons, MainUnit, FunctionsLib, OutputUnit, Globals, GraphLib, DataProcs, MatrixLib, - PointsUnit, ExpSmoothUnit, DifferenceUnit, FFTUnit, PolynomialUnit, + PointsUnit, DifferenceUnit, ContextHelpUnit; type @@ -23,9 +29,8 @@ type Panel1: TPanel; Panel2: TPanel; ResetBtn: TButton; - CancelBtn: TButton; ComputeBtn: TButton; - ReturnBtn: TButton; + CloseBtn: TButton; PlotChk: TCheckBox; StatsChk: TCheckBox; RMatChk: TCheckBox; @@ -72,19 +77,32 @@ type procedure InBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); - procedure ReturnBtnClick(Sender: TObject); + procedure CloseBtnClick(Sender: TObject); procedure RowBtnClick(Sender: TObject); + procedure VarListSelectionChange(Sender: TObject; User: boolean); + private { private declarations } FAutoSized: Boolean; + procedure UpdateBtnStates; + + private + FExpSmoothAlpha: Double; + function CalcMean(const pts: DblDyneVec; NoPts: Integer): Double; + procedure ExponentialSmooth(var Pts: DblDyneVec; NoPts: Integer); + procedure Four1(var data: DblDyneVec; nn: LongWord; isign: integer); + procedure Fourier(var data: DblDyneVec; n, npts: integer); + procedure FourierSmooth(var Pts: DblDyneVec; NoPts: Integer); + procedure GetPts(var pts: DblDyneVec; var NoPts: Integer; DepVar: Integer); + procedure MovingAverage(var Pts: DblDyneVec; NoPts: Integer); + procedure PlotDifferencesForLag(var Pts: DblDyneVec; NoPts: Integer); + procedure PolyFit(const pts: DblDyneVec; var avg: DblDyneVec; NoPts: integer); + procedure PolynomialSmooth(var Pts: DblDyneVec; NoPts: Integer); + procedure RealFT(var data: DblDyneVec; n: LongWord; isign: integer); + procedure RemoveMeans(var Pts: DblDyneVec; NoPts: Integer; AMean: Double); + public { public declarations } - procedure four1(VAR data : DblDyneVec; nn : longword; isign : integer); - procedure RealFT(VAR data : DblDyneVec; n : longword; isign : integer); - procedure Fourier(VAR data : DblDyneVec; n : integer; npts : integer); - procedure PolyFit(VAR pts : DblDyneVec; VAR avg : DblDyneVec; - NoPts : integer); - end; var @@ -94,62 +112,62 @@ implementation uses Math, - MoveAvgUnit, AutoPlotUnit; + MoveAvgUnit, AutoPlotUnit, PolynomialUnit, ExpSmoothUnit, FFTUnit; { TAutoCorrFrm } procedure TAutoCorrFrm.ResetBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - VarList.Clear; - DepVarEdit.Text := ''; - MaxLagEdit.Text := '30'; - StatsChk.Checked := false; - RmatChk.Checked := false; - PartialsChk.Checked := false; - PlotChk.Checked := true; - ResidChk.Checked := false; - DifferenceChk.Checked := false; - PolyChk.Checked := false; - MeanChk.Checked := false; - MoveAvgChk.Checked := false; - ExpSmoothChk.Checked := false; - FourierSmoothChk.Checked := false; - YuleWalkerChk.Checked := false; - FromCaseEdit.Text := ''; - ToCaseEdit.Text := ''; - AllCasesBtn.Checked := true; - InBtn.Enabled := true; - OutBtn.Enabled := false; - AlphaEdit.Text := '0.05'; - ProjPtsEdit.Text := ''; - if ColBtn.Checked = true then - begin - for i := 1 to OS3MainFrm.DataGrid.ColCount - 1 do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - end - else begin - for i := 1 to NoCases do - begin - if IsFiltered(i) then continue; - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[0,i]); - end; - end; + VarList.Clear; + DepVarEdit.Text := ''; + MaxLagEdit.Text := '30'; + StatsChk.Checked := false; + RmatChk.Checked := false; + PartialsChk.Checked := false; + PlotChk.Checked := true; + ResidChk.Checked := false; + DifferenceChk.Checked := false; + PolyChk.Checked := false; + MeanChk.Checked := false; + MoveAvgChk.Checked := false; + ExpSmoothChk.Checked := false; + FourierSmoothChk.Checked := false; + YuleWalkerChk.Checked := false; + FromCaseEdit.Text := ''; + ToCaseEdit.Text := ''; + AllCasesBtn.Checked := true; + AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL); + ProjPtsEdit.Text := ''; + if ColBtn.Checked then + for i := 1 to OS3MainFrm.DataGrid.ColCount - 1 do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]) + else + for i := 1 to NoCases do + begin + if IsFiltered(i) then continue; + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[0,i]); + end; + FExpSmoothAlpha := 0.99; + UpdateBtnStates; end; -procedure TAutoCorrFrm.ReturnBtnClick(Sender: TObject); +procedure TAutoCorrFrm.CloseBtnClick(Sender: TObject); begin Close; end; procedure TAutoCorrFrm.RowBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - VarList.Clear; - for i := 1 to NoCases do VarList.Items.Add(OS3MainFrm.DataGrid.Cells[0,i]); - GroupBox2.Caption := 'Include Columns:'; - AllCasesBtn.Caption := 'All Variables'; - OnlyCasesBtn.Caption := 'Only Columns From:'; + VarList.Clear; + for i := 1 to NoCases do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[0,i]); + GroupBox2.Caption := 'Include Columns:'; + AllCasesBtn.Caption := 'All Variables'; + OnlyCasesBtn.Caption := 'Only Columns From:'; end; procedure TAutoCorrFrm.FormActivate(Sender: TObject); @@ -159,12 +177,11 @@ begin if FAutoSized then exit; - w := MaxValue([HelpBtn.Width, ResetBtn.Width, CancelBtn.Width, ComputeBtn.Width, ReturnBtn.Width]); + w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); HelpBtn.Constraints.MinWidth := w; ResetBtn.Constraints.MinWidth := w; - CancelBtn.Constraints.MinWidth := w; ComputeBtn.Constraints.MinWidth := w; - ReturnBtn.Constraints.MinWidth := w; + CloseBtn.Constraints.MinWidth := w; Panel1.Constraints.MinWidth := GroupBox2.Left + GroupBox2.Width - Panel1.Left; Panel1.Constraints.MinHeight := Panel2.Top + Panel2.Height - Panel1.Top; @@ -179,8 +196,8 @@ end; procedure TAutoCorrFrm.FormCreate(Sender: TObject); begin Assert(OS3MainFrm <> nil); - if OutputFrm = nil then Application.CreateForm(TOutputFrm, OutputFrm); if PointsFrm = nil then Application.CreateForm(TPointsFrm, PointsFrm); + FExpSmoothAlpha := 0.99; end; procedure TAutoCorrFrm.FormShow(Sender: TObject); @@ -197,714 +214,453 @@ end; procedure TAutoCorrFrm.ComputeBtnClick(Sender: TObject); var - X, Y, count, covzero, mean : double; - uplimit, lowlimit, varresid, StdErr, alpha: double; - NoPts, DepVar, maxlag, lag, noproj : integer; - i, j, k, ncors, npoints, nvalues, t : integer; - Means, StdDevs, PartCors, residual, betas, rxy, pts, avg : DblDyneVec; - correlations, a : DblDyneMat; - RowLabels, ColLabels : StrDyneVec; - Title : string; - r, vx, vy, sx, sy, mx, my, UCL, LCL, Yhat, Constant : double; - outline, cellstring : string; - ColNoSelected : IntDyneVec; - NoSelected : integer; - Msg : string; - zconf, samptrans, z : double; - confidence, StdDevY : double; - //upper : array[0..300] of double; - lagvalue : array[0..300] of integer; - + X, Y, count, covzero, mean: double; + uplimit, lowlimit, varresid, StdErr, lAlpha: double; + NoPts, DepVar, maxlag, lag, noproj: integer; + i, j, k, ncors, npoints: integer; + Means, StdDevs, PartCors, residual, betas, rxy, pts, avg: DblDyneVec; + correlations, a: DblDyneMat; + RowLabels, ColLabels: StrDyneVec; + Title: string; + r, vx, vy, sx, sy, mx, my, UCL, LCL, Yhat, Constant: double; + ColNoSelected: IntDyneVec; + NoSelected: integer; + zconf, samptrans: double; + confidence: double; + lReport: TStrings; begin - OutputFrm.RichEdit.Clear; - - SetLength(ColNoSelected,NoVariables); - if ColBtn.Checked = true then + SetLength(ColNoSelected, NoVariables); + if ColBtn.Checked then + begin + // get column of the selected variable + DepVar := 0; + for i := 1 to NoVariables do + if (OS3MainFrm.DataGrid.Cells[i,0] = DepVarEdit.Text) then DepVar := i; + if (DepVar = 0)then begin - // get column of the selected variable - DepVar := 0; - for i := 1 to NoVariables do - if (OS3MainFrm.DataGrid.Cells[i,0] = DepVarEdit.Text) then DepVar := i; - if (DepVar = 0)then - begin - ShowMessage('No variable selected to analyze.'); - exit; - end; - ColNoSelected[0] := DepVar; - NoSelected := 1; - // get no. of valid points - NoPts := 0; - for i := 1 to NoCases do - if ValidValue(i,DepVar) then NoPts := NoPts + 1; - end - else begin // get row of the selected case - DepVar := 0; - for i := 1 to NoCases do - begin - if NOT GoodRecord(i,NoSelected,ColNoSelected) then continue; - if (OS3MainFrm.DataGrid.Cells[0,i] = DepVarEdit.Text) then DepVar := i; - end; - if (DepVar = 0)then - begin - ShowMessage('No variable selected to analyze.'); - exit; - end; - ColNoSelected[0] := DepVar; - NoSelected := 1; - NoPts := NoVariables; + MessageDlg('No variable selected to analyze.', mtError, [mbOK], 0); + exit; end; + ColNoSelected[0] := DepVar; + NoSelected := 1; - // Get the alpha level and the maximum lag values - alpha := 1.0 - StrToFloat(AlphaEdit.Text); - if ProjectChk.Checked then noproj := StrToInt(ProjPtsEdit.Text) else noproj := 0; - maxlag := StrToInt(MaxLagEdit.Text); - if maxlag > NoPts div 2 then maxlag := NoPts div 2; - if StrToInt(MaxLagEdit.Text) > maxlag then MaxLagEdit.Text := IntToStr(maxlag); - npoints := maxlag + 2; + // get no. of valid points + NoPts := 0; + for i := 1 to NoCases do + if ValidValue(i,DepVar) then NoPts := NoPts + 1; + end else + begin // get row of the selected case + DepVar := 0; + for i := 1 to NoCases do + begin + if not GoodRecord(i, NoSelected, ColNoSelected) then continue; + if (OS3MainFrm.DataGrid.Cells[0,i] = DepVarEdit.Text) then DepVar := i; + end; + if (DepVar = 0)then + begin + MessageDlg('No variable selected to analyze.', mtError,[mbOK], 0); + exit; + end; + ColNoSelected[0] := DepVar; + NoSelected := 1; + NoPts := NoVariables; + end; - // allocate space for covariance and correlation matrices, etc. - SetLength(correlations,npoints+1,npoints+1); - SetLength(Means,npoints); - SetLength(StdDevs,npoints); - SetLength(RowLabels,npoints); - SetLength(ColLabels,npoints); - SetLength(PartCors,npoints); - SetLength(a,npoints,npoints); - SetLength(betas,npoints); - SetLength(rxy,npoints); - SetLength(pts,NoPts+noproj+10); - SetLength(avg,NoPts+noproj+10); - SetLength(residual,NoPts+noproj+10); + // Get the alpha level and the maximum lag values + if AlphaEdit.Text = '' then + begin + AlphaEdit.Setfocus; + MessageDlg('Alpha level is not specified.', mtError, [mbOK], 0); + exit; + end; + if TryStrToFloat(AlphaEdit.Text, lAlpha) and (lAlpha > 0) and (lAlpha < 1) then + lAlpha := 1.0 - lAlpha + else + begin + AlphaEdit.SetFocus; + MessageDlg('Alpha level must be a valid number between 0 and 1.', mtError, [mbOK], 0); + exit; + end; - // Initialize arrays + if MaxLagEdit.Text = '' then + begin + MaxLagEdit.SetFocus; + MessageDlg('Input required.', mtError, [mbOK], 0); + exit; + end; + if TryStrToInt(MaxLagEdit.Text, maxlag) then + begin + if maxlag > NoPts div 2 then + maxlag := NoPts div 2; + if StrToInt(MaxLagEdit.Text) > maxlag then + MaxLagEdit.Text := IntToStr(maxlag); + nPoints := maxlag + 2; + end else + begin + MaxLagEdit.SetFocus; + MessageDlg('Valid number required.', mtError, [mbOK], 0); + exit; + end; + { + maxlag := StrToInt(MaxLagEdit.Text); + if maxlag > NoPts div 2 then + maxlag := NoPts div 2; + if StrToInt(MaxLagEdit.Text) > maxlag then + MaxLagEdit.Text := IntToStr(maxlag); + npoints := maxlag + 2; } + + noProj := 0; + if ProjectChk.Checked then + begin + if ProjPtsEdit.Text = '' then + begin + ProjPtsEdit.SetFocus; + MessageDlg('Projection points not specified', mtError, [mbOK], 0); + exit; + end; + if not TryStrToInt(ProjPtsEdit.Text, noProj) or (noProj < 0) then + begin + ProjPtsEdit.SetFocus; + MessageDlg('Valid positive number required.', mtError, [mbOK], 0); + exit; + end; + noproj := StrToInt(ProjPtsEdit.Text) + end; + + // allocate space for covariance and correlation matrices, etc. + SetLength(correlations, npoints+1, npoints+1); + SetLength(Means, npoints); + SetLength(StdDevs, npoints); + SetLength(RowLabels, npoints); + SetLength(ColLabels, npoints); + SetLength(PartCors, npoints); + SetLength(a, npoints, npoints); + SetLength(betas, npoints); + SetLength(rxy, npoints); + SetLength(pts, NoPts+noproj+10); + SetLength(avg, NoPts+noproj+10); + SetLength(residual, NoPts+noproj+10); + + lReport := TStringList.Create; + try + // Initialize arrays for i := 0 to npoints-1 do begin - for j := 0 to npoints - 1 do - begin - correlations[i,j] := 0.0; - a[i,j] := 0.0; - end; - Means[i] := 0.0; - StdDevs[i] := 0.0; - cellstring := 'Lag '; - cellstring := cellstring + IntToStr(i); - RowLabels[i] := cellstring; - ColLabels[i] := RowLabels[i]; - PartCors[i] := 0.0; - betas[i] := 0.0; + for j := 0 to npoints - 1 do + begin + correlations[i,j] := 0.0; + a[i,j] := 0.0; + end; + Means[i] := 0.0; + StdDevs[i] := 0.0; + RowLabels[i] := 'Lag ' + IntToStr(i); + ColLabels[i] := RowLabels[i]; + PartCors[i] := 0.0; + betas[i] := 0.0; end; + uplimit := 0.0; lowlimit := 0.0; covzero := 0.0; // Get points to analyze - if ColBtn.Checked = true then + GetPts(pts, noPts, DepVar); + if noPts = 0 then begin - if AllCasesBtn.Checked = true then - begin - for i := 1 to NoPts do - begin - if NOT ValidValue(i,DepVar) then continue; - pts[i-1] := StrToFloat(OS3MainFrm.DataGrid.Cells[DepVar,i]); - end; - end - else begin - NoPts := 0; - for i := StrToInt(FromCaseEdit.Text) to StrToInt(ToCaseEdit.Text) do - begin - if NOT ValidValue(i,DepVar) then continue; - pts[NoPts] := StrToFloat(OS3MainFrm.DataGrid.Cells[DepVar,i]); - NoPts := NoPts + 1; - end; - end; - end - else begin // row button selected - if AllCasesBtn.Checked = true then - begin - for i := 1 to NoPts do - begin - if Not ValidValue(DepVar,i) then continue; - pts[i-1] := StrToFloat(OS3MainFrm.DataGrid.Cells[i,DepVar]); - end; - end - else begin - NoPts := 0; - for i := StrToInt(FromCaseEdit.Text) to StrToInt(ToCaseEdit.Text) do - begin - if Not ValidValue(DepVar,i) then continue; - pts[NoPts] := StrToFloat(OS3MainFrm.DataGrid.Cells[i,DepVar]); - NoPts := NoPts + 1; - end; - end; + MessageDlg('No data points found.', mtError, [mbOk], 0); + exit; end; + count := NoPts; // Calculate mean of all values - mean := 0.0; - count := NoPts; - for i := 1 to NoPts do mean := mean + pts[i-1]; - - correlations[0,0] := 1.0; - mean := mean / count; + mean := CalcMean(pts, NoPts); // Remove mean from all observations if elected - if (MeanChk.Checked) then - for i := 1 to NoPts do pts[i-1] := pts[i-1] - mean; + if MeanChk.Checked then + RemoveMeans(pts, noPts, mean); + + correlations[0,0] := 1.0; // Get differences for lag specified - if (DifferenceChk.Checked) then - begin - if DifferenceFrm = nil then - Application.CreateForm(TDifferenceFrm, DifferenceFrm); - if (DifferenceFrm.ShowModal = mrOK) then - begin - lag := StrToInt(DifferenceFrm.LagEdit.Text); - for i := 0 to NoPts - 1 do avg[i] := pts[i]; - for j := 1 to StrToInt(DifferenceFrm.OrderEdit.Text) do - begin - for i := NoPts downto lag do - begin - avg[i] := avg[i] - avg[i-lag]; - end; - end; - end; - // plot the original and differenced values - PointsFrm.pts := pts; - PointsFrm.avg := avg; - PointsFrm.NoCases := NoPts; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Differenced'; - Msg := 'No. points = '; - Msg := Msg + IntToStr(NoCases); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.Title := 'Differencing Smoothed'; - PointsFrm.Caption := 'Difference Smoothing'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - if (ResidChk.Checked = true) then // calculate and plot residuals; - begin - varresid := 0.0; - for i := 0 to NoPts - 1 do - begin - residual[i] := pts[i] - avg[i]; - varresid := varresid + (residual[i] * residual[i]); - end; - varresid := varresid / NoPts; - StdErr := sqrt(varresid); - // plot the residuals - PointsFrm.pts := pts; - PointsFrm.avg := residual; - PointsFrm.NoCases := NoPts; - Msg := 'Std. Err. Residuals = '; - Msg := Msg + FloatToStr(StdErr); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Residuals'; - PointsFrm.Title := 'Residuals from Difference Smoothing'; - PointsFrm.Caption := 'Difference Residuals'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - end; - // replace original points with smoothed values - for i := 0 to NoPts - 1 do - pts[i] := avg[i]; - end; + if DifferenceChk.Checked then + PlotDifferencesForLag(Pts, NoPts); // Get moving average if checked - if (MoveAvgChk.Checked) then - begin - if MoveAvgFrm = nil then - Application.CreateForm(TMoveAvgFrm, MoveAvgFrm); - MoveAvgFrm.ShowModal; - nvalues := MoveAvgFrm.order; - if (nvalues > 0) then - begin - // plot the original points and the smoothed average - for i := nvalues to NoPts - nvalues - 1 do - begin - avg[i] := pts[i] * MoveAvgFrm.W[0]; // middle value - for j := 1 to nvalues do // left values - avg[i] := avg[i] + (pts[i-j] * MoveAvgFrm.W[j]); - for j := 1 to nvalues do // right values - avg[i] := avg[i] + (pts[i+j] * MoveAvgFrm.W[j]); - end; - // fill in unestimable averages with original points - for i := 0 to nvalues - 1 do // left values - begin - avg[i] := pts[i] * MoveAvgFrm.W[0]; - for j := 1 to nvalues do - avg[i] := avg[i] + (pts[i+j] * 2.0 * MoveAvgFrm.W[j]); - end; - for i := NoPts - nvalues to NoPts - 1 do //right values - begin - avg[i] := pts[i] * MoveAvgFrm.W[0]; - for j := 1 to nvalues do - avg[i] := avg[i] + (pts[i-j] * 2.0 * MoveAvgFrm.W[j]); - end; - if ProjectChk.Checked then - begin - for i := 0 to noproj-1 do - begin - avg[NoPts+i] := avg[NoPts-1]; - pts[NoPts+i] := pts[NoPts-1]; - end; - end; - // plot the points - PointsFrm.pts := pts; - PointsFrm.avg := avg; - PointsFrm.NoCases := NoPts+noproj; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Smoothed'; - Msg := 'No. points = '; - Msg := Msg + IntToStr(NoPts); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.Title := 'Moving Average Smoothed'; - PointsFrm.Caption := 'Moving Average Smoothing'; - PointsFrm.ShowModal; - end; - if (ResidChk.Checked = true) then // calculate and plot residuals; - begin - varresid := 0.0; - for i := 0 to NoPts - 1 do - begin - residual[i] := pts[i] - avg[i]; - varresid := varresid + (residual[i] * residual[i]); - end; - varresid := varresid / NoPts; - StdErr := sqrt(varresid); - // plot the residuals - PointsFrm.pts := pts; - PointsFrm.avg := residual; - PointsFrm.NoCases := NoPts; - Msg := 'Std. Err. Residuals = '; - Msg := Msg + FloatToStr(StdErr); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Residuals'; - PointsFrm.Title := 'Residuals from Moving Average'; - PointsFrm.Caption := 'Moving Average Residuals'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - end; - // replace original points with smoothed values - for i := 0 to (NoPts + noproj - 1) do pts[i] := avg[i]; - end; + if MoveAvgChk.Checked then + MovingAverage(Pts, NoPts); - // do exponential smoothing if requested - if (ExpSmoothChk.Checked = true) then - begin - if ExpSmoothFrm = nil then - Application.CreateForm(TExpSmoothFrm, ExpSmoothFrm); - ExpSmoothFrm.ShowModal; - alpha := ExpSmoothFrm.alpha; - avg[0] := pts[0]; // set first value := to observed - for t := 1 to NoPts - 1 do // case pointer - begin - avg[t] := alpha * pts[t]; - avg[t] := avg[t] + (1.0 - alpha) * avg[t-1]; - end; - if ProjectChk.Checked then - begin - for i := 0 to noproj-1 do - begin - avg[NoPts+i] := alpha * pts[NoPts+i-1]; - avg[NoPts+i] := avg[NoPts+i] + ((1.0 - alpha) * avg[NoPts+i-1]); - pts[NoPts+i] := avg[NoPts+i]; - end; - end; - // plot the points - PointsFrm.pts := pts; - PointsFrm.avg := avg; - PointsFrm.NoCases := NoPts+noproj; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Smoothed'; - PointsFrm.Title := 'Exponential Smoothed'; - PointsFrm.Caption := 'Exponential Smoothing'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - if (ResidChk.Checked = true) then // calculate and plot residuals; - begin - varresid := 0.0; - for i := 0 to NoPts - 1 do - begin - residual[i] := pts[i] - avg[i]; - varresid := varresid + (residual[i] * residual[i]); - end; - varresid := varresid / NoPts; - StdErr := sqrt(varresid); - // plot the residuals - PointsFrm.pts := pts; - PointsFrm.avg := residual; - PointsFrm.NoCases := NoPts; - Msg := 'Std. Err. Residuals = '; - Msg := Msg + FloatToStr(StdErr); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Residuals'; - PointsFrm.Title := 'Residuals from Exponential Smoothing'; - PointsFrm.Caption := 'Exponential Residuals'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - end; - // replace original points with smoothed values - for i := 0 to (NoPts + noproj - 1) do pts[i] := avg[i]; - end; + // Do exponential smoothing if requested + if ExpSmoothChk.Checked then + ExponentialSmooth(pts, NoPts); // Fast Fourier smoothing, if requested - if (FourierSmoothChk.Checked = true) then - begin - for i := 0 to NoPts - 1 do avg[i] := pts[i]; - if ProjectChk.Checked then - begin - for i := 0 to noproj - 1 do - begin - avg[i] := pts[NoPts-1-noproj+i]; - pts[i] := avg[i]; - end; - end; - if FFTFrm = nil then - Application.CreateForm(TFFTFrm, FFTFrm); - FFTFrm.NptsEdit.Text := IntToStr(NoPts+noproj+1); - FFTFrm.ShowModal; - nvalues := StrToInt(FFTFrm.NptsEdit.Text); - fourier(avg,nvalues,nvalues); - PointsFrm.pts := pts; - PointsFrm.avg := avg; - PointsFrm.NoCases := NoPts+noproj; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Smoothed'; - PointsFrm.Title := 'Fourier Smoothed'; - PointsFrm.Caption := 'Fourier Smoothing'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - if (ResidChk.Checked = true) then // calculate and plot residuals; - begin - varresid := 0.0; - for i := 0 to NoPts - 1 do - begin - residual[i] := pts[i] - avg[i]; - varresid := varresid + (residual[i] * residual[i]); - end; - varresid := varresid / NoPts; - StdErr := sqrt(varresid); - // plot the residuals - PointsFrm.pts := pts; - PointsFrm.avg := residual; - PointsFrm.NoCases := NoPts; - Msg := 'Std. Err. Residuals = '; - Msg := Msg + FloatToStr(StdErr); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Residuals'; - PointsFrm.Title := 'Residuals from Fourier Smoothing'; - PointsFrm.Caption := 'Fourier Residuals'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - end; - // replace original points with smoothed values - for i := 0 to (NoPts + noproj - 1) do pts[i] := avg[i]; - end; + if FourierSmoothChk.Checked then + FourierSmooth(pts, NoPts); // Get polynomial regression fit if elected - if (PolyChk.Checked) then - begin - if PolynomialFrm = nil then - Application.CreateForm(TPolynomialFrm, PolynomialFrm); - - if (PolynomialFrm.ShowModal = mrOk) then - begin - if ProjectChk.Checked then - begin - for i := 0 to noproj - 1 do - begin - avg[i] := pts[NoPts-1-noproj+i]; - pts[i] := avg[i]; - end; - end; - PolyFit(pts,avg,NoPts+noproj); - // plot original and smoothed data - PointsFrm.pts := pts; - PointsFrm.avg := avg; - PointsFrm.NoCases := NoPts+noproj; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Smoothed'; - PointsFrm.Title := 'Polynomial Smoothed'; - PointsFrm.Caption := 'Polynomial Smoothing'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - // plot residuals if checked - if (ResidChk.Checked) then - begin - varresid := 0.0; - for i := 0 to NoPts - 1 do - begin - residual[i] := pts[i] - avg[i]; - varresid := varresid + (residual[i] * residual[i]); - end; - varresid := varresid / NoPts; - StdErr := sqrt(varresid); - // plot the residuals - PointsFrm.pts := pts; - PointsFrm.avg := residual; - PointsFrm.NoCases := NoPts; - Msg := 'Std. Err. Residuals = '; - Msg := Msg + FloatToStr(StdErr); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Residuals'; - PointsFrm.Title := 'Residuals from Polynomial Smoothing'; - PointsFrm.Caption := 'Polynomial Residuals'; - PointsFrm.ShowModal; -// PointsFrm.PtsPlot(self); - end; - end; - - // replace original points with smoothed values - for i := 0 to (NoPts + noproj - 1) do pts[i] := avg[i]; - end; + if PolyChk.Checked then + PolynomialSmooth(pts, NoPts); // get mean and variance of (transformed?) points mean := 0.0; - for i := 0 to NoPts - 1 do mean := mean + pts[i]; + for i := 0 to NoPts - 1 do + mean := mean + pts[i]; mean := mean / NoPts; - for i := 1 to NoPts do + for i := 0 to NoPts-1 do + if MeanChk.Checked then + covzero := covzero + sqr(pts[i]) + else + covzero := covzero + sqr(pts[i] - mean); + covzero := covzero / NoPts; + + // get correlations for each lag 0 to maxlag + if StatsChk.Checked then begin - X := pts[i-1]; - if (MeanChk.Checked = true) then - covzero := covzero + sqr(X) - else - covzero := covzero + sqr(X - mean); + lReport.Add('Overall mean: %8.3f', [mean]); + lReport.Add('Variance: %8.3f', [covzero]); + lReport.Add(''); + + lReport.Add(' Lag Rxy MeanX MeanY Std.Dev.X Std.Dev.Y Cases LCL UCL '); + lReport.Add('----- -------- -------- -------- ---------- ---------- -------- -------- --------'); end; - covzero := covzero / count; - outline := format('Overall mean = %8.3f, variance = %8.3f',[mean,covzero]); - OutputFrm.RichEdit.Lines.Add(outline); + confidence := StrToFloat(AlphaEdit.Text); + ncors := 0; + if maxlag > NoPts - 3 then + begin + maxlag := NoPts - 3; + maxlagedit.Text := IntToStr(maxlag); + end; - // get correlations for each lag 0 to maxlag - confidence := StrToFloat(AlphaEdit.Text); - ncors := 0; - OutputFrm.RichEdit.Lines.Add('Lag Rxy MeanX MeanY Std.Dev.X Std.Dev.Y Cases LCL UCL'); - OutputFrm.RichEdit.Lines.Add(''); - if maxlag > NoPts-3 then - begin - maxlag := NoPts - 3; - maxlagedit.Text := IntToStr(maxlag); - end; - for lag := 0 to maxlag do - begin - r := 0.0; - vx := 0.0; - vy := 0.0; - mx := 0.0; - my := 0.0; - Count := 0.0; - lagvalue[lag] := lag; - for i := 1 to (NoPts - lag) do - begin - X := pts[i-1]; - Y := pts[i-1+lag]; - if (MeanChk.Checked = true) then r := r + (X * Y) - else r := r + ((X - mean) * (Y - mean)); - vx := vx + (X * X); - vy := vy + (Y * Y); - mx := mx + X; - my := my + Y; - Count := Count + 1.0; - end; - r := r / NoPts; - vx := vx - (mx * mx / Count); - vx := vx / (Count - 1.0); - sx := sqrt(vx); - vy := vy - (my * my / Count); - vy := vy / (Count - 1.0); - sy := sqrt(vy); - mx := mx / Count; - my := my / Count; - r := r / covzero; - if (abs(r) < 1.0) then samptrans := ln((1.0 + r) / (1.0 - r)) / 2.0; - // if above failed, r := 1.0 - StdErr := sqrt(1.0 / (NoPts - 3.0)); - zconf := abs(inversez(confidence / 2.0)); - if (abs(r) < 1.0) then - begin - z := samptrans / StdErr; - UCL := samptrans + (zconf * StdErr); - LCL := samptrans - (zconf * StdErr); - UCL := (exp(2.0 * UCL) - 1.0) / (exp(2.0 * UCL) + 1.0); - LCL := (exp(2.0 * LCL) - 1.0) / (exp(2.0 * LCL) + 1.0); - end - else - begin - UCL := 1.0; - LCL := 1.0; - end; - //upper[lag] := UCL; - //lower[lag] := LCL; - outline := format('%4d %9.4f %9.4f %9.4f %9.4f %9.4f %9.0f %9.4f %9.4f', - [lag, r, mx, my, sx, sy, Count, LCL, UCL]); - OutputFrm.RichEdit.Lines.Add(outline); - ncors := ncors + 1; - correlations[0,lag] := r; - correlations[lag,0] := r; - end; // next lag - OutputFrm.ShowModal; + for lag := 0 to maxlag do + begin + r := 0.0; + vx := 0.0; + vy := 0.0; + mx := 0.0; + my := 0.0; + Count := 0.0; +// lagvalue[lag] := lag; + for i := 1 to (NoPts - lag) do + begin + X := pts[i-1]; + Y := pts[i-1+lag]; + if MeanChk.Checked then + r := r + X * Y + else + r := r + (X - mean) * (Y - mean); + vx := vx + sqr(X); + vy := vy + sqr(Y); + mx := mx + X; + my := my + Y; + Count := Count + 1.0; + end; + r := r / NoPts; + vx := vx - sqr(mx) / Count; + vx := vx / (Count - 1.0); + sx := sqrt(vx); + + vy := vy - sqr(my) / Count; + vy := vy / (Count - 1.0); + sy := sqrt(vy); + + mx := mx / Count; + my := my / Count; + r := r / covzero; + if (abs(r) < 1.0) then + samptrans := ln((1.0 + r) / (1.0 - r)) / 2.0; + stdErr := sqrt(1.0 / (NoPts - 3.0)); + zconf := abs(InverseZ(confidence * 0.5)); + if (abs(r) < 1.0) then + begin + //z := samptrans / StdErr; + UCL := samptrans + zconf * StdErr; + LCL := samptrans - zconf * StdErr; + UCL := (exp(2.0 * UCL) - 1.0) / (exp(2.0 * UCL) + 1.0); + LCL := (exp(2.0 * LCL) - 1.0) / (exp(2.0 * LCL) + 1.0); + end else + begin + UCL := 1.0; + LCL := 1.0; + end; + if StatsChk.Checked then + lReport.Add('%4d %9.4f %9.4f %9.4f %11.4f %11.4f %9.0f %9.4f %9.4f', + [lag, r, mx, my, sx, sy, Count, LCL, UCL] + ); + ncors := ncors + 1; + correlations[0,lag] := r; + correlations[lag,0] := r; + end; // next lag // build correlation matrix - for i := 0 to maxlag do correlations[i,i] := 1.0; + for i := 0 to maxlag do + correlations[i,i] := 1.0; for i := 1 to maxlag do - begin - for j := i+1 to maxlag do - begin - correlations[i,j] := correlations[0,j-i]; - correlations[j,i] := correlations[i,j]; - end; - end; + for j := i+1 to maxlag do + begin + correlations[i,j] := correlations[0,j-i]; + correlations[j,i] := correlations[i,j]; + end; // Print the correlation matrix if elected - if (RmatChk.Checked = true) then + if RmatChk.Checked then begin - OutputFrm.RichEdit.Clear; - Title := 'Matrix of Lagged Variable: '; - Title := Title + DepVarEdit.Text; - MAT_PRINT(correlations,maxlag+1,maxlag+1,Title,RowLabels,ColLabels,NoPts); - OutputFrm.ShowModal; + if lReport.Count > 0 then + begin + lReport.Add(''); + lReport.Add(DIVIDER); + lReport.Add(''); + end; + Title := 'Matrix of Lagged Variable: ' + DepVarEdit.Text; + MatPrint(correlations, maxlag+1, maxlag+1, Title, RowLabels, ColLabels, NoPts, lReport); end; // Calculate partial correlations PartCors[0] := 1.0; for i := 1 to maxlag do // start at lag 1 begin + for j := 1 to i do + begin + for k := 1 to i do + a[j-1,k-1] := correlations[j,k]; + rxy[j-1] := correlations[0,j]; + end; + + SVDinverse(a, i); + + // get betas as product of inverse times vector + for j := 1 to i do + begin + betas[j-1] := 0.0; + for k := 1 to i do + betas[j-1] := betas[j-1] + (a[j-1,k-1] * rxy[k-1]); + end; + + // get regression constant + // Note - since variance of Y and each X is the same, B = beta for an X + Constant := 0; + if not MeanChk.Checked then + begin for j := 1 to i do + Constant := Constant + betas[j-1] * Mean; + Constant := Mean - Constant; + end; + + // calculate predicted value and residual + // Note - the dependent variable predicted is the next value in the + // time series using each of the previous time period values + Yhat := 0.0; + for j := 0 to i-1 do + Yhat := Yhat + (betas[j] * pts[j]); + Yhat := Yhat + Constant; + avg[i] := Yhat; + residual[i] := pts[i] - Yhat; + + // print betas if elected + if YuleWalkerChk.Checked then + begin + if lReport.Count > 0 then begin - for k := 1 to i do - begin - a[j-1,k-1] := correlations[j,k]; - end; - rxy[j-1] := correlations[0,j]; + lReport.Add(''); + if i = 1 then lReport.Add(DIVIDER) else lReport.Add(DIVIDER_SMALL); + lReport.Add(''); end; - SVDinverse(a, i); + Title := 'Yule-Walker Coefficients for lag ' + IntToStr(i); + DynVectorPrint(betas, i, Title, ColLabels, NoPts, lReport); + lReport.Add('Constant: %10.3f', [Constant]); + end; - // get betas as product of inverse times vector - for j := 1 to i do - begin - betas[j-1] := 0.0; - for k := 1 to i do betas[j-1] := betas[j-1] + (a[j-1,k-1] * rxy[k-1]); - end; - - // get regression constant - // Note - since variance of Y and each X is the same, B = beta for an X - Constant := 0; - if MeanChk.Checked = false then - begin - for j := 1 to i do Constant := Constant + betas[j-1] * Mean; - Constant := Mean - Constant; - end; - - // calculate predicted value and residual - // Note - the dependent variable predicted is the next value in the - // time series using each of the previous time period values - Yhat := 0.0; - StdDevY := sqrt(covzero); - for j := 0 to i-1 do Yhat := Yhat + (betas[j] * pts[j]); - Yhat := Yhat + Constant; - avg[i] := Yhat; - residual[i] := pts[i] - Yhat; - - // print betas if elected - if (YuleWalkerChk.Checked) then - begin - OutputFrm.RichEdit.Clear; - Title := 'Yule-Walker Coefficients for lag ' + IntToStr(i); - DynVectorPrint(betas,i,Title,ColLabels,NoPts); - outline := format('Constant = %10.3f',[Constant]); - OutputFrm.RichEdit.Lines.Add(outline); - OutputFrm.ShowModal; - end; - - PartCors[i] := betas[i-1]; + PartCors[i] := betas[i-1]; end; // next i (lag from 1 to maxlag) // print partial correlations if elected - if (PartialsChk.Checked = true) then + if PartialsChk.Checked then begin - OutputFrm.RichEdit.Clear; - Title := 'Partial Correlation Coefficients'; - DynVectorPrint(PartCors,maxlag,Title,ColLabels,NoPts); - OutputFrm.ShowModal; + if lReport.Count > 0 then + begin + lReport.Add(''); + lReport.Add(DIVIDER); + lReport.Add(''); + end; + Title := 'Partial Correlation Coefficients'; + DynVectorPrint(PartCors, maxlag, Title, ColLabels, NoPts, lReport); end; // plot correlations if elected uplimit := 1.96 * (1.0 / sqrt(count)); lowlimit := -1.96 * (1.0 / sqrt(count)); - if (PlotChk.Checked = true) then + if PlotChk.Checked then begin - if AutoPlotFrm = nil then - Application.CreateForm(TAutoPlotFrm, AutoPlotFrm); - for i := 0 to maxlag do rxy[i] := correlations[0][i]; - AutoPlotFrm.PlotPartCors := true; - AutoPlotFrm.PlotLimits := true; - AutoPlotFrm.correlations := rxy; - AutoPlotFrm.partcors := PartCors; - AutoPlotFrm.uplimit := uplimit; - AutoPlotFrm.lowlimit := lowlimit; - AutoPlotFrm.npoints := maxlag+1; - AutoPlotFrm.DepVarEdit := DepVarEdit.Text; -// AutoPlotFrm.AutoPlot; - AutoPlotFrm.ShowModal; + if AutoPlotFrm = nil then + Application.CreateForm(TAutoPlotFrm, AutoPlotFrm); + for i := 0 to maxlag do + rxy[i] := correlations[0][i]; + AutoPlotFrm.PlotPartCors := true; + AutoPlotFrm.PlotLimits := true; + AutoPlotFrm.correlations := rxy; + AutoPlotFrm.partcors := PartCors; + AutoPlotFrm.uplimit := uplimit; + AutoPlotFrm.lowlimit := lowlimit; + AutoPlotFrm.npoints := maxlag+1; + AutoPlotFrm.DepVarEdit := DepVarEdit.Text; + AutoPlotFrm.ShowModal; end; if MRegSmoothChk.Checked then begin - // calculate predicted values and residuals for remaining points - // Note - the dependent variable predicted is the next value in - // the time series using each of the previous time period values - // as predictors - for i := maxlag to (NoPts + noproj - 1) do - begin - Yhat := 0.0; - for j := 0 to maxlag do Yhat := Yhat + (betas[j] * pts[i-maxlag+j]); - Yhat := Yhat + Constant; - avg[i] := Yhat; - residual[i] := pts[i] - Yhat; - end; - // plot points smoothed by autoregression - avg[0] := pts[0]; - PointsFrm.pts := pts; - PointsFrm.avg := avg; - PointsFrm.NoCases := NoPts + noproj; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Smoothed'; - PointsFrm.Title := 'Autoregressive Smoothed'; - PointsFrm.Caption := 'Autoregression Smoothing'; - PointsFrm.ShowModal; + // calculate predicted values and residuals for remaining points + // Note - the dependent variable predicted is the next value in + // the time series using each of the previous time period values + // as predictors + for i := maxlag to (NoPts + noproj - 1) do + begin + Yhat := 0.0; + for j := 0 to maxlag do + Yhat := Yhat + (betas[j] * pts[i-maxlag+j]); + Yhat := Yhat + Constant; + avg[i] := Yhat; + residual[i] := pts[i] - Yhat; + end; - // plot residuals if elected - if (ResidChk.Checked) then - begin - varresid := 0.0; - residual[0] := 0.0; - for i := 1 to maxlag do - begin -// residual[i] := pts[i] - avg[i]; - varresid := varresid + (residual[i] * residual[i]); - end; - varresid := varresid / maxlag; - StdErr := sqrt(varresid); - // plot the residuals - PointsFrm.pts := pts; - PointsFrm.avg := residual; - PointsFrm.NoCases := NoPts; - Msg := 'Std. Err. Residuals = '; - Msg := Msg + FloatToStr(StdErr); - PointsFrm.MsgEdit.Text := Msg; - PointsFrm.LabelOne := 'Original'; - PointsFrm.LabelTwo := 'Residuals'; - PointsFrm.Title := 'Residuals from Autoregression Smoothing'; - PointsFrm.Caption := 'Autoregressive Residuals'; - PointsFrm.ShowModal; - end; + // plot points smoothed by autoregression + avg[0] := pts[0]; + PointsFrm.pts := pts; + PointsFrm.avg := avg; + PointsFrm.NoCases := NoPts + noproj; + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Smoothed'; + PointsFrm.Title := 'Autoregressive Smoothed'; + PointsFrm.Caption := 'Autoregression Smoothing'; + PointsFrm.ShowModal; + + // plot residuals if elected + if ResidChk.Checked then + begin + varresid := 0.0; + residual[0] := 0.0; + for i := 1 to maxlag do + varresid := varresid + sqr(residual[i]); + varresid := varresid / maxlag; + StdErr := sqrt(varresid); + + // plot the residuals + PointsFrm.pts := pts; + PointsFrm.avg := residual; + PointsFrm.NoCases := NoPts; + PointsFrm.MsgEdit.Text := 'Std. Err. Residuals: ' + FloatToStr(StdErr); + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Residuals'; + PointsFrm.Title := 'Residuals from Autoregression Smoothing'; + PointsFrm.Caption := 'Autoregressive Residuals'; + PointsFrm.ShowModal; + end; end; - // clean up the heap + DisplayReport(lReport); + + finally + lReport.Free; + residual := nil; avg := nil; pts := nil; @@ -918,278 +674,282 @@ begin Means := nil; correlations := nil; ColNoSelected := nil; - - OutputFrm.RichEdit.Clear; + end; end; procedure TAutoCorrFrm.ColBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - VarList.Clear; - for i := 1 to OS3MainFrm.DataGrid.ColCount - 1 do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - GroupBox2.Caption := 'Include Cases:'; - AllCasesBtn.Caption := 'All Cases'; - OnlyCasesBtn.Caption := 'Only Cases From:'; + VarList.Clear; + for i := 1 to OS3MainFrm.DataGrid.ColCount - 1 do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + GroupBox2.Caption := 'Include Cases:'; + AllCasesBtn.Caption := 'All Cases'; + OnlyCasesBtn.Caption := 'Only Cases From:'; end; procedure TAutoCorrFrm.InBtnClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := VarList.ItemIndex; - DepVarEdit.Text := VarList.Items.Strings[index]; - VarList.Items.Delete(index); - OutBtn.Enabled := true; - InBtn.Enabled := false; + index := VarList.ItemIndex; + if (index > -1) and (DepVarEdit.Text = '') then + begin + DepVarEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + UpdateBtnStates; + end; end; procedure TAutoCorrFrm.OutBtnClick(Sender: TObject); begin - VarList.Items.Add(DepVarEdit.Text); - DepVarEdit.Text := ''; - InBtn.Enabled := true; - OutBtn.Enabled := false; + if DepVarEdit.Text <> '' then + begin + VarList.Items.Add(DepVarEdit.Text); + DepVarEdit.Text := ''; + UpdateBtnStates; + end; end; -procedure TAutoCorrFrm.four1(var data: DblDyneVec; nn: longword; isign: integer); +procedure TAutoCorrFrm.Four1(var data: DblDyneVec; nn: longword; isign: integer); var - n,mmax,m,j,istep, i : longword; - wtemp,wr,wpr,wpi,wi,theta : double; - tempr,tempi : double; - + n, mmax, m, j, istep, i: longword; + wtemp, wr, wpr, wpi, wi, theta: double; + tempr, tempi: double; begin - n := 2 * nn; - j := 1; - i := 1; - while i < n do - begin - if (j > i) then - begin - tempr := data[j]; - tempi := data[j+1]; - data[j] := data[i]; - data[j+1] := data[i+1]; - data[i] := tempr; - data[i+1] := tempi; - end; - m := n div 2; - while (m >= 2) and (j > m) do - begin - j := j - m; - m := m div 2; - end; - j := j + m; - i := i + 2; - end; - mmax := 2; - while (n > mmax) do + n := 2 * nn; + j := 1; + i := 1; + while i < n do + begin + if (j > i) then begin - istep := 2 * mmax; - theta := isign * (6.28318530717959 / mmax); - wtemp := sin(0.5 * theta); - wpr := -2.0 * wtemp * wtemp; - wpi := sin(theta); - wr := 1.0; - wi := 0.0; - m := 1; - while m < mmax do - begin - i := m; - while i <= n do - begin - j := i + mmax; - tempr := wr * data[j] - wi * data[j+1]; - tempi := wr * data[j+1] + wi * data[j]; - data[j] := data[i] - tempr; - data[j+1] := data[i+1] - tempi; - data[i] := data[i] + tempr; - data[i+1] := data[i+1] + tempi; - i := i + istep; - end; - wtemp := wr; - wr := wr * wpr - wi * wpi + wr; - wi := wi * wpr + wtemp * wpi + wi; - m := m + 2; - end; - mmax := istep; - end; -end; - -procedure TAutoCorrFrm.realft(var data: DblDyneVec; n: longword; isign: integer); -var - i,i1,i2,i3,i4,np3 : integer; // was: longword; - c1,c2,h1r,h1i,h2r,h2i : double; - wr,wi,wpr,wpi,wtemp,theta : double; - -begin - c1 := 0.5; - theta := 3.141592653589793 / ( n div 2); - if (isign = 1) then - begin - c2 := -0.5; - four1(data,n div 2,1); - end else - begin - c2 := 0.5; - theta := -theta; - end; - wtemp := sin(0.5 * theta); - wpr := -2.0 * wtemp * wtemp; - wpi := sin(theta); - wr := 1.0 + wpr; - wi := wpi; - np3 := n + 3; - for i := 2 to n div 2 do - begin - i1 := i + i - 1; - i2 := 1 + i1; - i3 := np3 - i2; - i4 := 1 + i3; - h1r := c1 * (data[i1] + data[i3]); - h1i := c1 * (data[i2] - data[i4]); - h2r := -c2 * (data[i2] + data[i4]); - h2i := c2 * (data[i1] - data[i3]); - data[i1] := h1r + wr * h2r - wi * h2i; - data[i2] := h1i + wr * h2i + wi * h2r; - data[i3] := h1r - wr * h2r + wi * h2i; - data[i4] := -h1i + wr * h2i + wi * h2r; - wtemp := wr; - wr := wtemp * wpr - wi * wpi + wr; - wi := wi * wpr + wtemp * wpi + wi; - end; - if (isign = 1) then - begin - h1r := data[1]; - data[1] := h1r + data[2]; - data[2] := h1r - data[2]; - end else - begin - h1r := data[1]; - data[1] := c1 * (h1r + data[2]); - data[2] := c1 * (h1r - data[2]); - four1(data,n div 2,-1); - end; -end; - -procedure TAutoCorrFrm.fourier(var data: DblDyneVec; n: integer; npts: integer ); -var - nmin, m, mo2, i, k, j : integer; - yn, y1, rn1, fac, cnst : double; - y : DblDyneVec; - -begin - m := 2; - nmin := n + (2 * npts); - while (m < nmin) do m := m * 2; - cnst := npts / m; - cnst := cnst * cnst; - SetLength(y,m+1); - for i := 0 to n - 1 do y[i+1] := data[i]; - y1 := y[1]; - yn := y[n]; - rn1 := 1.0 / (n - 1); - for j := 1 to n do y[j] := y[j] + (-rn1 * (y1 * (n - j) + y1 * (j - 1))); - for j := n+1 to m do y[j] := 0.0; - mo2 := m div 2; - realft(y,mo2,1); - y[1] := y[1] / mo2; - fac := 1.0; - for j := 1 to mo2 - 1 do - begin - k := 2 * j + 1; - if (fac <> 0) then - begin - fac := (1.0 - cnst * j * j) / mo2; - if ( fac < 0.0) then fac := 0.0; - y[k] := fac * y[k]; - y[k + 1] := fac * y[k + 1]; - end - else y[k + 1] := 0.0; - y[k] := 0.0; + tempr := data[j]; + tempi := data[j+1]; + data[j] := data[i]; + data[j+1] := data[i+1]; + data[i] := tempr; + data[i+1] := tempi; end; - fac := (1.0 - 0.25 * npts * npts) / mo2; - if (fac < 0.0) then fac := 0.0; - y[2] := y[2] * fac; - realft(y,mo2,-1); - for j := 1 to n do y[j] := y[j] + rn1 * (y1 * (n - j) + yn * (j - 1)); - for j := 0 to n - 1 do data[j] := y[j+1]; - y := nil; + m := n div 2; + while (m >= 2) and (j > m) do + begin + j := j - m; + m := m div 2; + end; + j := j + m; + i := i + 2; + end; + mmax := 2; + while (n > mmax) do + begin + istep := 2 * mmax; + theta := isign * TWO_PI / mmax; + wtemp := sin(0.5 * theta); + wpr := -2.0 * wtemp * wtemp; + wpi := sin(theta); + wr := 1.0; + wi := 0.0; + m := 1; + while m < mmax do + begin + i := m; + while i <= n do + begin + j := i + mmax; + tempr := wr * data[j] - wi * data[j+1]; + tempi := wr * data[j+1] + wi * data[j]; + data[j] := data[i] - tempr; + data[j+1] := data[i+1] - tempi; + data[i] := data[i] + tempr; + data[i+1] := data[i+1] + tempi; + i := i + istep; + end; + wtemp := wr; + wr := wr * wpr - wi * wpi + wr; + wi := wi * wpr + wtemp * wpi + wi; + m := m + 2; + end; + mmax := istep; + end; end; -procedure TAutoCorrFrm.PolyFit(var pts: DblDyneVec; var avg: DblDyneVec; +procedure TAutoCorrFrm.RealFt(var data: DblDyneVec; n: longword; isign: integer); +var + i,i1,i2,i3,i4,np3 : integer; // was: longword; + c1,c2,h1r,h1i,h2r,h2i : double; + wr,wi,wpr,wpi,wtemp,theta : double; +begin + c1 := 0.5; + theta := PI / ( n div 2); + if (isign = 1) then + begin + c2 := -0.5; + Four1(data, n div 2, 1); + end else + begin + c2 := 0.5; + theta := -theta; + end; + wtemp := sin(0.5 * theta); + wpr := -2.0 * wtemp * wtemp; + wpi := sin(theta); + wr := 1.0 + wpr; + wi := wpi; + np3 := n + 3; + for i := 2 to n div 2 do + begin + i1 := i + i - 1; + i2 := 1 + i1; + i3 := np3 - i2; + i4 := 1 + i3; + h1r := c1 * (data[i1] + data[i3]); + h1i := c1 * (data[i2] - data[i4]); + h2r := -c2 * (data[i2] + data[i4]); + h2i := c2 * (data[i1] - data[i3]); + data[i1] := h1r + wr * h2r - wi * h2i; + data[i2] := h1i + wr * h2i + wi * h2r; + data[i3] := h1r - wr * h2r + wi * h2i; + data[i4] := -h1i + wr * h2i + wi * h2r; + wtemp := wr; + wr := wtemp * wpr - wi * wpi + wr; + wi := wi * wpr + wtemp * wpi + wi; + end; + + if (isign = 1) then + begin + h1r := data[1]; + data[1] := h1r + data[2]; + data[2] := h1r - data[2]; + end else + begin + h1r := data[1]; + data[1] := c1 * (h1r + data[2]); + data[2] := c1 * (h1r - data[2]); + Four1(data,n div 2,-1); + end; +end; + +procedure TAutoCorrFrm.Fourier(var data: DblDyneVec; n, npts: integer); +var + nmin, m, mo2, i, k, j: integer; + yn, y1, rn1, fac, cnst: double; + y: DblDyneVec; +begin + m := 2; + nmin := n + 2*npts; + while (m < nmin) do m := m * 2; + + cnst := sqr(npts / m); + + SetLength(y, m+1); + for i := 0 to n - 1 do + y[i+1] := data[i]; + y1 := y[1]; + yn := y[n]; + rn1 := 1.0 / (n - 1); + for j := 1 to n do + y[j] := y[j] + (-rn1 * (y1 * (n - j) + y1 * (j - 1))); + for j := n+1 to m do + y[j] := 0.0; + mo2 := m div 2; + + RealFT(y, mo2, 1); + + y[1] := y[1] / mo2; + fac := 1.0; + for j := 1 to mo2 - 1 do + begin + k := 2 * j + 1; + if (fac <> 0) then + begin + fac := (1.0 - cnst * j * j) / mo2; + if (fac < 0.0) then fac := 0.0; + y[k] := fac * y[k]; + y[k + 1] := fac * y[k + 1]; + end + else + y[k + 1] := 0.0; + y[k] := 0.0; + end; + + fac := (1.0 - 0.25 * npts * npts) / mo2; + if (fac < 0.0) then fac := 0.0; + y[2] := y[2] * fac; + + RealFT(y,mo2,-1); + + for j := 1 to n do + y[j] := y[j] + rn1 * (y1 * (n - j) + yn * (j - 1)); + for j := 0 to n - 1 do + data[j] := y[j+1]; + + y := nil; +end; + +procedure TAutoCorrFrm.PolyFit(const pts: DblDyneVec; var avg: DblDyneVec; NoPts: integer); var - X : DblDyneMat; - XY : DblDyneVec; - XTX : DblDyneMat; - Beta : DblDyneVec; - t, Yhat : double; - i, j, k, order : integer; - RowLabels, ColLabels : StrDyneVec; - + X: DblDyneMat; + XY: DblDyneVec; + XTX: DblDyneMat; + Beta: DblDyneVec; + t, Yhat: double; + i, j, k, order: integer; + RowLabels, ColLabels: StrDyneVec; begin - order := StrToInt(PolynomialFrm.PolyEdit.Text); - SetLength(X,NoPts,order+1); - SetLength(XTX,order+2,order+2); - SetLength(XY,order+1); - SetLength(Beta,order+1); - SetLength(RowLabels,NoPts+1); - SetLength(ColLabels,NoPts+1); + order := StrToInt(PolynomialFrm.PolyEdit.Text); + SetLength(X,NoPts,order+1); + SetLength(XTX,order+2,order+2); + SetLength(XY,order+1); + SetLength(Beta,order+1); + SetLength(RowLabels,NoPts+1); + SetLength(ColLabels,NoPts+1); - // initialize - for i := 0 to NoPts - 1 do + // initialize + for i := 0 to NoPts - 1 do + for j := 0 to order do + X[i,j] := 0.0; + + for i := 0 to order do + begin + XY[i] := 0.0; + Beta[i] := 0.0; + for j := 0 to order do + XTX[i,j] := 0.0; + end; + + for i := 0 to NoPts - 1 do + for j := 0 to order do begin - for j := 0 to order do - begin - X[i,j] := 0.0; - end; - end; - for i := 0 to order do - begin - XY[i] := 0.0; - Beta[i] := 0.0; - for j := 0 to order do - begin - XTX[i,j] := 0.0; - end; + t := i+1; + X[i,j] := Power(t,j); end; - for i := 0 to NoPts - 1 do - begin - for j := 0 to order do - begin - t := i+1; - X[i,j] := Power(t,j); - end; - end; + // print the X matrix as a check + for i := 0 to NoPts - 1 do + RowLabels[i] := 'Case' + IntToStr(i+1); - // print the X matrix as a check - for i := 0 to NoPts - 1 do - begin - RowLabels[i] := 'Case' + IntToStr(i+1); - end; - for i := 0 to order+1 do - begin - ColLabels[i] := 'Order' + IntToStr(i); - end; -{ + for i := 0 to order+1 do + ColLabels[i] := 'Order' + IntToStr(i); + + { OutputFrm.RichEdit.Clear; Title := 'X Matrix'; DynMatPrint(X,NoPts,order+1,Title,RowLabels,ColLabels,NoPts); OutputFrm.ShowModal; } - // Get X transpose times X - for j := 0 to order do + // Get X transpose times X + for j := 0 to order do + begin + for k := 0 to order do begin - for k := 0 to order do - begin - XTX[j,k] := 0.0; - for i := 0 to NoPts - 1 do - begin - XTX[j,k] := XTX[j,k] + (X[i,j] * X[i,k]); - end; - end; + XTX[j,k] := 0.0; + for i := 0 to NoPts - 1 do + XTX[j,k] := XTX[j,k] + (X[i,j] * X[i,k]); end; + end; { // print the XTX matrix OutputFrm.RichEdit.Clear; @@ -1197,14 +957,10 @@ begin DynMatPrint(XTX,order+2,order+2,Title,ColLabels,ColLabels,NoPts); OutputFrm.ShowModal; } - // Get X transpose Y - for j := 0 to order do - begin - for i := 0 to NoPts - 1 do - begin - XY[j] := XY[j] + (X[i,j] * pts[i]); - end; - end; + // Get X transpose Y + for j := 0 to order do + for i := 0 to NoPts - 1 do + XY[j] := XY[j] + (X[i,j] * pts[i]); { // print the XY vector OutputFrm.RichEdit.Clear; @@ -1212,8 +968,8 @@ begin DynVectorPrint(XY,order+1,Title,ColLabels,NoPts); OutputFrm.ShowModal; } - // get inverse of XTX - SVDinverse(XTX,order+1); + // get inverse of XTX + SVDinverse(XTX, order+1); { // print the inverse matrix OutputFrm.RichEdit.Clear; @@ -1221,39 +977,523 @@ begin DynMatPrint(XTX,order+2,order+2,Title,ColLabels,ColLabels,NoPts); OutputFrm.ShowModal; } - // get betas - for j := 0 to order do - begin - for k := 0 to order do - begin - Beta[j] := Beta[j] + (XTX[j,k] * XY[k]); - end; - end; -{ + // get betas + for j := 0 to order do + for k := 0 to order do + Beta[j] := Beta[j] + (XTX[j,k] * XY[k]); + + { // print the betas OutputFrm.RichEdit.Clear; Title := 'Betas vector'; DynVectorPrint(Beta,order+1,Title,ColLabels,NoPts); OutputFrm.ShowModal; } - // get predicted values - for i := 0 to NoPts - 1 do + // get predicted values + for i := 0 to NoPts - 1 do + begin + Yhat := 0.0; + t := i; + for j := 0 to order do + Yhat := Yhat + (Beta[j] * Power(t,j)); + avg[i] := Yhat; + end; + + //cleanup + ColLabels := nil; + RowLabels := nil; + Beta := nil; + XY := nil; + XTX := nil; + X := nil; +end; + +procedure TAutoCorrFrm.UpdateBtnStates; +begin + InBtn.Enabled := (VarList.ItemIndex > -1) and (DepVarEdit.Text = ''); + OutBtn.Enabled := (DepVarEdit.Text <> ''); +end; + +procedure TAutoCorrFrm.VarListSelectionChange(Sender: TObject; User: boolean); +begin + UpdateBtnStates; +end; + + +{ Routines called from ComputeBtnClick } + +function TAutoCorrFrm.CalcMean(const Pts: DblDyneVec; NoPts: Integer): Double; +var + i: Integer; +begin + Result := 0.0; + for i := 0 to NoPts-1 do + Result := Result + Pts[i]; + Result := Result / NoPts; +end; + +procedure TAutoCorrFrm.ExponentialSmooth(var Pts: DblDyneVec; NoPts: Integer); +var + F: TExpSmoothFrm; + noProj: Integer; + avg: DblDyneVec; + residual: DblDyneVec; + i: Integer; + varRes: Double; + stdErr: Double; +begin + F := TExpSmoothFrm.Create(nil); + try + F.Alpha := FExpSmoothAlpha; + if F.ShowModal <> mrOK then + exit; + + FExpSmoothAlpha := F.Alpha; + + if ProjectChk.Checked then + noProj := StrToInt(ProjPtsEdit.Text) + else + noProj := 0; + + SetLength(avg, NoPts + noProj); + avg[0] := pts[0]; // set first value = to observed + for i := 1 to NoPts - 1 do // case pointer + avg[i] := FExpSmoothAlpha * pts[i] + (1.0 - FExpSmoothAlpha) * avg[i-1]; + + if ProjectChk.Checked then begin - Yhat := 0.0; - t := i; - for j := 0 to order do Yhat := Yhat + (Beta[j] * Power(t,j)); - avg[i] := Yhat; + for i := 0 to noproj-1 do + begin + avg[NoPts + i] := FExpSmoothAlpha * pts[NoPts + i - 1]; + avg[NoPts + i] := avg[NoPts + i] + (1.0 - FExpSmoothAlpha) * avg[NoPts + i - 1]; + pts[NoPts + i] := avg[NoPts + i]; + end; end; - //cleanup - ColLabels := nil; - RowLabels := nil; - Beta := nil; - XY := nil; - XTX := nil; - X := nil; + // plot the points + PointsFrm.pts := pts; + PointsFrm.avg := avg; + PointsFrm.NoCases := NoPts + noproj; + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Smoothed'; + PointsFrm.Title := 'Exponential Smoothed'; + PointsFrm.Caption := 'Exponential Smoothing'; + PointsFrm.ShowModal; + + if ResidChk.Checked then // calculate and plot residuals; + begin + SetLength(residual, NoPts); + varRes := 0.0; + for i := 0 to NoPts - 1 do + begin + residual[i] := pts[i] - avg[i]; + varRes := varRes + sqr(residual[i]); + end; + varRes := varRes / NoPts; + StdErr := sqrt(varRes); + + // plot the residuals + PointsFrm.pts := pts; + PointsFrm.avg := residual; + PointsFrm.NoCases := NoPts; + PointsFrm.MsgEdit.Text := 'Std. Err. Residuals: ' + FloatToStr(StdErr); + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Residuals'; + PointsFrm.Title := 'Residuals from Exponential Smoothing'; + PointsFrm.Caption := 'Exponential Residuals'; + PointsFrm.ShowModal; + end; + + // replace original points with smoothed values + for i := 0 to (NoPts + noproj - 1) do + pts[i] := avg[i]; + + finally + F.Free; + end; end; +procedure TAutoCorrFrm.FourierSmooth(var Pts: DblDyneVec; NoPts: Integer); +var + F: TFFTFrm; + avg: DblDyneVec; + residual: DblDyneVec; + NValues: Integer; + i: Integer; + noProj: Integer; + varRes: double; + stdErr: Double; +begin + if ProjectChk.Checked then + noProj := StrToInt(ProjPtsEdit.Text) + else + noProj := 0; + NValues := NoPts + noProj + 1; + + F := TFFtFrm.Create(nil); + try + F.NptsEdit.Text := IntToStr(NValues); + if F.ShowModal <> mrOK then + exit; + + SetLength(avg, NoPts + noProj); + if ProjectChk.Checked then + begin + for i := 0 to noproj - 1 do + begin + avg[i] := pts[NoPts-1-noproj+i]; + pts[i] := avg[i]; + end; + end; + + Fourier(avg, NValues, NValues); + + PointsFrm.pts := pts; + PointsFrm.avg := avg; + PointsFrm.NoCases := NoPts + noproj; + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Smoothed'; + PointsFrm.Title := 'Fourier Smoothed'; + PointsFrm.Caption := 'Fourier Smoothing'; + PointsFrm.ShowModal; + + // calculate and plot residuals; + if ResidChk.Checked then + begin + SetLength(residual, NoPts); + varRes := 0.0; + for i := 0 to NoPts - 1 do + begin + residual[i] := pts[i] - avg[i]; + varRes := varRes + sqr(residual[i]); + end; + varRes := varRes / NoPts; + stdErr := sqrt(varRes); + + // plot the residuals + PointsFrm.pts := pts; + PointsFrm.avg := residual; + PointsFrm.NoCases := NoPts; + PointsFrm.MsgEdit.Text := 'Std. Err. Residuals: ' + FloatToStr(StdErr); + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Residuals'; + PointsFrm.Title := 'Residuals from Fourier Smoothing'; + PointsFrm.Caption := 'Fourier Residuals'; + PointsFrm.ShowModal; + end; + + // replace original points with smoothed values + for i := 0 to (NoPts + noproj - 1) do pts[i] := avg[i]; + + finally + F.Free; + end; +end; + +procedure TAutoCorrFrm.GetPts(var Pts: DblDyneVec; var NoPts: Integer; + Depvar: Integer); +var + i: Integer; +begin + if ColBtn.Checked then + begin + if AllCasesBtn.Checked then + begin + for i := 1 to NoPts do + if ValidValue(i, DepVar) then + Pts[i-1] := StrToFloat(OS3MainFrm.DataGrid.Cells[DepVar, i]) + else + Pts[i-1] := NaN; // wp: added thid for defined crash because of undefined values + end else + begin + NoPts := 0; + for i := StrToInt(FromCaseEdit.Text) to StrToInt(ToCaseEdit.Text) do + begin + if ValidValue(i, DepVar) then continue; + Pts[NoPts] := StrToFloat(OS3MainFrm.DataGrid.Cells[DepVar, i]); + NoPts := NoPts + 1; + end; + end; + end else + begin + // row button selected + if AllCasesBtn.Checked then + begin + for i := 1 to NoPts do + if ValidValue(DepVar, i) then + Pts[i-1] := StrToFloat(OS3MainFrm.DataGrid.Cells[i, DepVar]) + else + Pts[i-1] := NaN; // wp: added thid for defined crash because of undefined values + end else + begin + NoPts := 0; + for i := StrToInt(FromCaseEdit.Text) to StrToInt(ToCaseEdit.Text) do + begin + if not ValidValue(DepVar,i) then continue; + pts[NoPts] := StrToFloat(OS3MainFrm.DataGrid.Cells[i,DepVar]); + NoPts := NoPts + 1; + end; + end; + end; +end; + +procedure TAutoCorrFrm.MovingAverage(var Pts: DblDyneVec; NoPts: Integer); +var + F: TMoveAvgFrm; + i, j: Integer; + nValues: Integer; + avg: DblDyneVec; + residual: DblDyneVec; + noProj: Integer; + varRes: Double; + stdErr: Double; +begin + F := TMoveAvgFrm.Create(nil); + try + if F.ShowModal <> mrOK then + exit; + nValues := F.Order; + if nValues <= 0 then + exit; + + if ProjectChk.Checked then + noProj := StrToInt(ProjPtsEdit.Text) + else + noProj := 0; + + // Calculate moving average + SetLength(avg, NoPts + NoProj); + for i := nValues to NoPts - nValues - 1 do + begin + avg[i] := Pts[i] * F.W[0]; // middle value + for j := 1 to nValues do + avg[i] := avg[i] + Pts[i-j] * F.W[j] + Pts[i+j] * F.W[j]; + // left values right values + end; + + // fill in unestimable averages with original points + for i := 0 to nValues - 1 do // left values + begin + avg[i] := pts[i] * F.W[0]; + for j := 1 to nvalues do + avg[i] := avg[i] + (pts[i+j] * 2.0 * F.W[j]); + end; + for i := NoPts - nValues to NoPts - 1 do //right values + begin + avg[i] := pts[i] * F.W[0]; + for j := 1 to nvalues do + avg[i] := avg[i] + (pts[i-j] * 2.0 * F.W[j]); + end; + + if ProjectChk.Checked then + begin + noProj := StrToInt(ProjPtsEdit.Text); + for i := 0 to NoProj-1 do + begin + avg[NoPts + i] := avg[NoPts - 1]; + pts[NoPts + i] := pts[NoPts - 1]; + end; + end; + + // plot the original points and the smoothed average + PointsFrm.pts := pts; + PointsFrm.avg := avg; + PointsFrm.NoCases := NoPts + noProj; + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Smoothed'; + PointsFrm.MsgEdit.Text := 'No. points: '+ IntToStr(NoPts); + PointsFrm.Title := 'Moving Average Smoothed'; + PointsFrm.Caption := 'Moving Average Smoothing'; + PointsFrm.ShowModal; + + // calculate and plot residuals; + if ResidChk.Checked then + begin + SetLength(residual, NoPts); + varRes := 0.0; + for i := 0 to NoPts - 1 do + begin + residual[i] := pts[i] - avg[i]; + varRes := varRes + sqr(residual[i]); + end; + varRes := varRes / NoPts; + stdErr := sqrt(varRes); + + // plot the residuals + PointsFrm.pts := pts; + PointsFrm.avg := residual; + PointsFrm.NoCases := NoPts; + PointsFrm.MsgEdit.Text := 'Std. Err. Residuals: ' + FloatToStr(StdErr); + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Residuals'; + PointsFrm.Title := 'Residuals from Moving Average'; + PointsFrm.Caption := 'Moving Average Residuals'; + PointsFrm.ShowModal; + end; + + // replace original points with smoothed values + for i := 0 to (NoPts + noproj - 1) do + pts[i] := avg[i]; + + finally + F.Free; + end; +end; + +procedure TAutoCorrFrm.PlotDifferencesForLag(var Pts: DblDyneVec; NoPts: Integer); +var + F: TDifferenceFrm; + lag: Integer; + avg: DblDyneVec; + residual: DblDyneVec; + varRes: Double; + stdErr: Double; + i, j: Integer; +begin + F := TDifferenceFrm.Create(nil); + try + if F.ShowModal <> mrOK then + exit; + + lag := StrToInt(MaxLagEdit.Text); + + SetLength(avg, NoPts); + for i := 0 to NoPts-1 do + avg[i] := pts[i]; + + for j := 1 to StrToInt(F.OrderEdit.Text) do + for i := NoPts downto lag do + avg[i] := avg[i] - avg[i - lag]; // wp: what with avg[0]..avg[lag] ? + + // plot the original and differenced values + PointsFrm.pts := pts; + PointsFrm.avg := avg; + PointsFrm.NoCases := NoPts; + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Differenced'; + PointsFrm.MsgEdit.Text := 'No. points = ' + IntToStr(NoCases); + PointsFrm.Title := 'Differencing Smoothed'; + PointsFrm.Caption := 'Difference Smoothing'; + PointsFrm.ShowModal; + + // calculate and plot residuals; + if ResidChk.Checked then + begin + SetLength(residual, NoPts); + varRes := 0.0; + for i := 0 to NoPts - 1 do + begin + residual[i] := pts[i] - avg[i]; + varRes := varRes + sqr(residual[i]); + end; + varRes := varRes / NoPts; + stdErr := sqrt(varRes); + + // plot the residuals + PointsFrm.pts := pts; + PointsFrm.avg := residual; + PointsFrm.NoCases := NoPts; + PointsFrm.MsgEdit.Text := 'Std. Err. Residuals: ' + FloatToStr(StdErr); + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Residuals'; + PointsFrm.Title := 'Residuals from Difference Smoothing'; + PointsFrm.Caption := 'Difference Residuals'; + PointsFrm.ShowModal; + end; + + // replace original points by smoothed values + for i := 0 to NoPts - 1 do + pts[i] := avg[i]; + finally + F.Free; + end; +end; + +procedure TAutoCorrFrm.PolynomialSmooth(var Pts: DblDyneVec; NoPts: Integer); +var + F: TPolynomialFrm; + noProj: Integer; + i: Integer; + avg: DblDyneVec; + residual: DblDyneVec; + varRes: Double; + stdErr: Double; +begin + F := TPolynomialFrm.Create(nil); + try + if F.ShowModal <> mrOK then + exit; + + if ProjectChk.Checked then + noProj := StrToInt(ProjPtsEdit.Text) + else + noProj := 0; + + SetLength(avg, NoPts + noProj); + if ProjectChk.Checked then + begin + for i := 0 to noproj - 1 do + begin + avg[i] := pts[NoPts-1-noproj+i]; + pts[i] := avg[i]; + end; + end; + + PolyFit(pts, avg, NoPts + noproj); + + // plot original and smoothed data + PointsFrm.pts := pts; + PointsFrm.avg := avg; + PointsFrm.NoCases := NoPts + noproj; + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Smoothed'; + PointsFrm.Title := 'Polynomial Smoothed'; + PointsFrm.Caption := 'Polynomial Smoothing'; + PointsFrm.ShowModal; + + // plot residuals if checked + if ResidChk.Checked then + begin + SetLength(residual, NoPts); + varRes := 0.0; + for i := 0 to NoPts - 1 do + begin + residual[i] := pts[i] - avg[i]; + varRes := varRes + sqr(residual[i]); + end; + varRes := varRes / NoPts; + stdErr := sqrt(varRes); + + // plot the residuals + PointsFrm.pts := pts; + PointsFrm.avg := residual; + PointsFrm.NoCases := NoPts; + PointsFrm.MsgEdit.Text := 'Std. Err. Residuals: ' + FloatToStr(StdErr); + PointsFrm.LabelOne := 'Original'; + PointsFrm.LabelTwo := 'Residuals'; + PointsFrm.Title := 'Residuals from Polynomial Smoothing'; + PointsFrm.Caption := 'Polynomial Residuals'; + PointsFrm.ShowModal; + end; + + // replace original points with smoothed values + for i := 0 to (NoPts + noproj - 1) do + pts[i] := avg[i]; + + finally + F.Free; + end; +end; + +procedure TAutoCorrFrm.RemoveMeans(var Pts: DblDyneVec; NoPts: Integer; AMean: Double); +var + i: Integer; +begin + for i := 0 to NoPts-1 do + Pts[i] := Pts[i] - AMean; +end; + + initialization {$I autocorunit.lrs} diff --git a/applications/lazstats/source/forms/analysis/correlation/autoplotunit.pas b/applications/lazstats/source/forms/analysis/correlation/autoplotunit.pas index 8ed44ebef..ee61a1f68 100644 --- a/applications/lazstats/source/forms/analysis/correlation/autoplotunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/autoplotunit.pas @@ -51,168 +51,168 @@ procedure TAutoPlotFrm.FormShow(Sender: TObject); begin Image1.Canvas.Brush.Color := clWhite; Image1.Canvas.FillRect(0, 0, Image1.Width, Image1.Height); -// AutoPlotFrm.Image1.Canvas.Clear; AutoPlot(self); end; procedure TAutoPlotFrm.PrintBtnClick(Sender: TObject); -var r : Trect; +var + R: Trect; begin - with Printer do - begin - Printer.Orientation := poPortrait; - r := Rect(20,20,printer.pagewidth-20,printer.pageheight div 2 + 20); - BeginDoc; - Canvas.StretchDraw(r,Image1.Picture.BitMap); - EndDoc; - end; + with Printer do + begin + Orientation := poPortrait; + R := Rect(20,20, PageWidth-20, PageHeight div 2 + 20); + BeginDoc; + try + Canvas.StretchDraw(R, Image1.Picture.BitMap); + finally + EndDoc; + end; + end; end; procedure TAutoPlotFrm.AutoPlot(Sender: TObject); var - topmarg, botmarg, leftmarg, rightmarg, verthi, horizlong : integer; - i, X, Y, middle, yincrement, xincrement, labelheight : integer; - labelstring : string; - labelstr : string; - corstep, yprop, scaley : double; - + topmarg, botmarg, leftmarg, rightmarg, verthi, horizlong: integer; + i, X, Y, middle, yincrement, xincrement, labelheight: integer; + labelstring: string; + corstep, yprop, scaley: double; begin - height := Image1.Canvas.Height; - width := Image1.Canvas.Width; - middle := height div 2; - topmarg := height div 10; - verthi := height - (2 * topmarg); - botmarg := topmarg + verthi; - leftmarg := width div 10; - horizlong := width - 2 * leftmarg; - rightmarg := leftmarg + horizlong; - yincrement := verthi div 20; - xincrement := horizlong div npoints; + height := Image1.Canvas.Height; + width := Image1.Canvas.Width; + middle := height div 2; + topmarg := height div 10; + verthi := height - 3 * topmarg; + botmarg := topmarg + verthi; + leftmarg := width div 10; + horizlong := width - 2 * leftmarg; + rightmarg := leftmarg + horizlong; + yincrement := verthi div 20; + xincrement := horizlong div npoints; -// AutoPlotFrm.Show; - Image1.Canvas.Pen.Color := clBlack; + Image1.Canvas.Pen.Color := clBlack; + Image1.Canvas.Font.Color := clBlack; - // print title at top, centered - labelstring := 'Autocorrelations analysis for :'; - labelstring := labelstring + DepVarEdit; - X := (leftmarg + horizlong div 2) - (Image1.Canvas.TextWidth(labelstring) div 2); - Y := 1; - Image1.Canvas.TextOut(X,Y,labelstring); + // print title at top, centered + labelstring := 'Autocorrelations analysis for ' + DepVarEdit; + X := leftmarg + (horizlong - Image1.Canvas.TextWidth(labelstring)) div 2; + Y := 1; + Image1.Canvas.TextOut(X, Y, labelstring); - // draw middle (zero correlation) axis - Y := middle; - Image1.Canvas.MoveTo(leftmarg,Y); - X := rightmarg; - Image1.Canvas.LineTo(X,Y); + // draw middle (zero correlation) axis + Image1.Canvas.Pen.Color := clBlack; + Image1.Canvas.Line(leftmarg, middle, rightmarg, middle); - // draw right axis - X := leftmarg; + // draw left axis + Image1.Canvas.Pen.Color := clBlack; + Image1.Canvas.Line(leftmarg, topmarg, leftmarg, botmarg); + + // correlation scale to left of vertical axis + corstep := 1.0; + for i := 0 to 20 do + begin + Y := topmarg + i * yincrement; + labelstring := Format('%4.2f -', [corstep]); + X := leftmarg - Image1.Canvas.TextWidth(labelstring); + Image1.Canvas.TextOut(X, Y, labelstring); + corstep := corstep - 0.1; + end; + + // Make legend axis on bottom + Image1.Canvas.Pen.Color := clBlack; + Y := botmarg; + Image1.Canvas.Line(leftmarg, Y, rightmarg, Y); + + Y := botmarg; + for i := 0 to npoints do + begin + X := leftmarg + xincrement * i; + labelstring := '|'; + Image1.Canvas.TextOut(X, Y, labelstring); + labelstring := IntToStr(i); + Y := Y + 5; + if odd(i) then + Image1.Canvas.TextOut(X, Y, labelstring); Y := botmarg; - Image1.Canvas.MoveTo(X,Y); - Y := topmarg; - Image1.Canvas.LineTo(X,Y); + end; - // correlation scale to left of vertical axis - corstep := 1.0; - for i := 0 to 20 do - begin - Y := topmarg + (i * yincrement); - labelstr := format('%4.2f -',[corstep]); - labelstring := labelstr; - X := leftmarg - Image1.Canvas.TextWidth(labelstring); - Image1.Canvas.TextOut(X,Y,labelstring); - corstep := corstep - 0.1; - end; + labelstring := 'LAG VALUE'; + X := leftmarg + (horizlong - Image1.Canvas.TextWidth(labelstring) div 2); + Y := botmarg + Image1.Canvas.TextHeight(labelstring) + 10; + Image1.Canvas.TextOut(X, Y, labelstring); - // Make legend axis on bottom - X := leftmarg; - Y := botmarg; - Image1.Canvas.MoveTo(X,Y); - X := rightmarg; - Image1.Canvas.LineTo(X,Y); - for i := 0 to npoints do - begin - X := leftmarg + (xincrement * i); - labelstring := '|'; - Image1.Canvas.TextOut(X,Y,labelstring); - labelstring := IntToStr(i); - Y := Y + 5; - if (i mod 2) = 1 then Image1.Canvas.TextOut(X,Y,labelstring); - Y := botmarg; - end; - labelstring := 'LAG VALUE'; - X := (leftmarg + horizlong div 2) - (Image1.Canvas.TextWidth(labelstring) div 2); - Y := botmarg + Image1.Canvas.TextHeight(labelstring); - Image1.Canvas.TextOut(X,Y,labelstring); + // Plot lines from correlation to correlation + Image1.Canvas.Pen.Color := clRed; + for i := 0 to npoints - 1 do + begin + yprop := (1.0 - correlations[i]) / 2.0; + scaley := yprop * verthi; + X := leftmarg + round(xincrement * i); + Y := topmarg + round(scaley); + if (i = 0)then + Image1.Canvas.MoveTo(X, Y) + else + Image1.Canvas.LineTo(X, Y); + Image1.Canvas.Ellipse(X-3, Y-3, X+3, Y+3); + end; - // Plot lines from correlation to correlation - Image1.Canvas.Pen.Color := clRed; + // Plot partial correlations + if PlotPartCors then + begin + Image1.Canvas.Pen.Color := clBlue; for i := 0 to npoints - 1 do begin - yprop := (1.0 - correlations[i]) / 2.0; - scaley := yprop * verthi; - X := leftmarg + round(xincrement * i); - Y := topmarg + round(scaley); - if (i = 0)then Image1.Canvas.MoveTo(X,Y) - else Canvas.LineTo(X,Y); - Image1.Canvas.Ellipse(X-3,Y-3,X+3,Y+3); + yprop := (1.0 - partcors[i]) / 2.0; + scaley := yprop * verthi; + X := leftmarg + round(xincrement * i); + Y := topmarg + round(scaley); + if (i = 0) then + Image1.Canvas.MoveTo(X,Y) + else + Image1.Canvas.LineTo(X,Y); + Image1.Canvas.Ellipse(X-3, Y-3, X+3, Y+3); end; + end; - // Plot partial correlations - if PlotPartCors then - begin - Image1.Canvas.Pen.Color := clBlue; - for i := 0 to npoints - 1 do - begin - yprop := (1.0 - partcors[i]) / 2.0; - scaley := yprop * verthi; - X := leftmarg + round(xincrement * i); - Y := topmarg + round(scaley); - if (i = 0) then Image1.Canvas.MoveTo(X,Y) - else Image1.Canvas.LineTo(X,Y); - Image1.Canvas.Ellipse(X-3,Y-3,X+3,Y+3); - end; - end; - - // Plot lines for upper and lower 95% confidence levels - if PlotLimits then - begin - Image1.Canvas.Pen.Color := clGreen; - yprop := (1.0 - uplimit) / 2.0; - scaley := yprop * verthi; - Y := topmarg + round(scaley); - Image1.Canvas.MoveTo(leftmarg,Y); - X := rightmarg; - Image1.Canvas.LineTo(X,Y); - yprop := (1.0 - lowlimit) / 2.0; - scaley := yprop * verthi; - Y := topmarg + round(scaley); - Image1.Canvas.MoveTo(leftmarg,Y); - X := rightmarg; - Image1.Canvas.LineTo(X,Y); - end; - - // Show legend at right + // Plot lines for upper and lower 95% confidence levels + if PlotLimits then + begin + Image1.Canvas.Pen.Color := clGreen; + yprop := (1.0 - uplimit) / 2.0; + scaley := yprop * verthi; + Y := topmarg + round(scaley); + Image1.Canvas.MoveTo(leftmarg,Y); X := rightmarg; - labelstring := 'Correlations'; - labelheight := Image1.Canvas.TextHeight(labelstring); - Y := 5 * labelheight; - Image1.Canvas.Font.Color := clRed; - Image1.Canvas.TextOut(X,Y,labelstring); - if PlotPartCors then - begin - labelstring := 'Partials'; - Y := 6 * labelheight; - Image1.Canvas.Font.Color := clBlue; - Image1.Canvas.TextOut(X,Y,labelstring); - end; - if PlotLimits then - begin - Y := 7 * labelheight; - labelstring := '95% C.I.'; - Image1.Canvas.Font.Color := clGreen; - Image1.Canvas.TextOut(X,Y,labelstring); - end; + Image1.Canvas.LineTo(X, Y); + yprop := (1.0 - lowlimit) / 2.0; + scaley := yprop * verthi; + Y := topmarg + round(scaley); + Image1.Canvas.MoveTo(leftmarg, Y); + X := rightmarg; + Image1.Canvas.LineTo(X,Y); + end; + + // Show legend at right + X := rightmarg; + labelstring := 'Correlations'; + labelheight := Image1.Canvas.TextHeight(labelstring); + Y := 5 * labelheight; + Image1.Canvas.Font.Color := clRed; + Image1.Canvas.TextOut(X, Y, labelstring); + if PlotPartCors then + begin + labelstring := 'Partials'; + Y := 6 * labelheight; + Image1.Canvas.Font.Color := clBlue; + Image1.Canvas.TextOut(X, Y, labelstring); + end; + if PlotLimits then + begin + Y := 7 * labelheight; + labelstring := '95% C.I.'; + Image1.Canvas.Font.Color := clGreen; + Image1.Canvas.TextOut(X, Y, labelstring); + end; end; procedure TAutoPlotFrm.FormActivate(Sender: TObject); diff --git a/applications/lazstats/source/forms/analysis/correlation/differenceunit.lfm b/applications/lazstats/source/forms/analysis/correlation/differenceunit.lfm index 04036971a..0e8036e2f 100644 --- a/applications/lazstats/source/forms/analysis/correlation/differenceunit.lfm +++ b/applications/lazstats/source/forms/analysis/correlation/differenceunit.lfm @@ -2,29 +2,30 @@ object DifferenceFrm: TDifferenceFrm Left = 611 Height = 115 Top = 292 - Width = 318 + Width = 308 AutoSize = True BorderStyle = bsDialog Caption = 'Differencing Specification' ClientHeight = 115 - ClientWidth = 318 + ClientWidth = 308 OnActivate = FormActivate OnShow = FormShow Position = poMainFormCenter LCLVersion = '2.1.0.0' object CancelBtn: TButton - AnchorSideLeft.Control = Owner AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom - Left = 128 + AnchorSideRight.Control = OKBtn + Left = 188 Height = 25 Top = 78 Width = 62 + Anchors = [akTop, akRight] AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'Cancel' ModalResult = 2 @@ -35,16 +36,20 @@ object DifferenceFrm: TDifferenceFrm AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom - Left = 202 + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + Left = 258 Height = 25 Top = 78 Width = 42 + Anchors = [akTop, akRight] AutoSize = True BorderSpacing.Top = 8 - BorderSpacing.Right = 16 + BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 Caption = 'OK' ModalResult = 1 + OnClick = OKBtnClick TabOrder = 3 end object HelpBtn: TButton @@ -52,13 +57,13 @@ object DifferenceFrm: TDifferenceFrm AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = CancelBtn - Left = 65 + Left = 129 Height = 25 Top = 78 Width = 51 Anchors = [akTop, akRight] AutoSize = True - BorderSpacing.Left = 16 + BorderSpacing.Left = 8 BorderSpacing.Top = 8 BorderSpacing.Bottom = 8 Caption = 'Help' @@ -69,14 +74,14 @@ object DifferenceFrm: TDifferenceFrm AnchorSideLeft.Control = Owner AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = Owner - Left = 68 + Left = 63 Height = 50 Top = 8 Width = 183 AutoSize = True - BorderSpacing.Left = 12 + BorderSpacing.Left = 24 BorderSpacing.Top = 8 - BorderSpacing.Right = 12 + BorderSpacing.Right = 24 BevelOuter = bvNone ClientHeight = 50 ClientWidth = 183 @@ -118,7 +123,7 @@ object DifferenceFrm: TDifferenceFrm Alignment = taRightJustify Anchors = [akTop, akRight] TabOrder = 0 - Text = '1' + Text = 'LagEdit' end object OrderEdit: TEdit AnchorSideTop.Control = LagEdit @@ -133,7 +138,7 @@ object DifferenceFrm: TDifferenceFrm Anchors = [akTop, akRight] BorderSpacing.Top = 4 TabOrder = 1 - Text = '1' + Text = 'OrderEdit' end end object Bevel1: TBevel @@ -145,7 +150,7 @@ object DifferenceFrm: TDifferenceFrm Left = 0 Height = 8 Top = 62 - Width = 318 + Width = 308 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 4 Shape = bsBottomLine diff --git a/applications/lazstats/source/forms/analysis/correlation/differenceunit.pas b/applications/lazstats/source/forms/analysis/correlation/differenceunit.pas index 2e59ff757..512db9b3e 100644 --- a/applications/lazstats/source/forms/analysis/correlation/differenceunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/differenceunit.pas @@ -25,8 +25,10 @@ type procedure FormActivate(Sender: TObject); procedure FormShow(Sender: TObject); procedure HelpBtnClick(Sender: TObject); + procedure OKBtnClick(Sender: TObject); private { private declarations } + function Validate(out AMsg: String; out AControl: TWinControl): boolean; public { public declarations } end; @@ -53,8 +55,8 @@ end; procedure TDifferenceFrm.FormShow(Sender: TObject); begin - LagEdit.Text := '1'; - OrderEdit.Text := '1'; + LagEdit.Text := '1'; + OrderEdit.Text := '1'; end; procedure TDifferenceFrm.HelpBtnClick(Sender: TObject); @@ -64,6 +66,54 @@ begin ContextHelpForm.HelpMessage((Sender as TButton).tag); end; +procedure TDifferenceFrm.OKBtnClick(Sender: TObject); +var + msg: String; + C: TWinControl; +begin + if not Validate(msg, C) then + begin + C.SetFocus; + MessageDlg(msg, mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + +function TDifferenceFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; +var + n: Integer; +begin + Result := false; + if LagEdit.Text = '' then + begin + AMsg := 'Input required.'; + AControl := LagEdit; + exit; + end; + if not TryStrToInt(LagEdit.Text, n) or (n < 0) then + begin + AMsg := 'Non-negative integer value required.'; + AControl := LagEdit; + exit; + end; + + if OrderEdit.Text = '' then + begin + AMsg := 'Input required.'; + AControl := OrderEdit; + exit; + end; + if not TryStrToInt(OrderEdit.Text, n) or (n < 0) then + begin + AMsg := 'Non-negative integer value required.'; + AControl := OrderEdit; + exit; + end; + + Result := true; +end; + + initialization {$I differenceunit.lrs} diff --git a/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.lfm b/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.lfm index 89ce225dc..ef139c637 100644 --- a/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.lfm +++ b/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.lfm @@ -9,27 +9,27 @@ object ExpSmoothFrm: TExpSmoothFrm ClientHeight = 131 ClientWidth = 352 OnActivate = FormActivate - OnShow = FormShow Position = poMainFormCenter LCLVersion = '2.1.0.0' object Label1: TLabel AnchorSideTop.Control = AlphaEdit AnchorSideTop.Side = asrCenter AnchorSideRight.Control = AlphaEdit - Left = 101 + Left = 115 Height = 15 Top = 12 - Width = 45 + Width = 31 Anchors = [akTop, akRight] + BorderSpacing.Left = 16 BorderSpacing.Right = 8 - Caption = 'Alpha = ' + Caption = 'Alpha' ParentColor = False end object Label2: TLabel - AnchorSideLeft.Control = Owner + AnchorSideLeft.Control = AlphaScroll AnchorSideTop.Control = AlphaScroll AnchorSideTop.Side = asrBottom - Left = 8 + Left = 24 Height = 15 Top = 66 Width = 15 @@ -41,9 +41,9 @@ object ExpSmoothFrm: TExpSmoothFrm object Label3: TLabel AnchorSideTop.Control = AlphaScroll AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner + AnchorSideRight.Control = AlphaScroll AnchorSideRight.Side = asrBottom - Left = 329 + Left = 313 Height = 15 Top = 66 Width = 15 @@ -63,6 +63,7 @@ object ExpSmoothFrm: TExpSmoothFrm Width = 44 Alignment = taRightJustify BorderSpacing.Top = 8 + BorderSpacing.Right = 16 TabOrder = 0 Text = '0.99' end @@ -72,17 +73,18 @@ object ExpSmoothFrm: TExpSmoothFrm AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - Left = 8 + Left = 16 Height = 23 Top = 39 - Width = 336 + Width = 320 Anchors = [akTop, akLeft, akRight] - BorderSpacing.Left = 8 + BorderSpacing.Left = 16 BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - Max = 1 + BorderSpacing.Right = 16 + Max = 99 + Min = 1 PageSize = 0 - Position = 1 + Position = 99 TabOrder = 1 OnChange = AlphaScrollChange end @@ -90,12 +92,13 @@ object ExpSmoothFrm: TExpSmoothFrm AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = OKBtn - Left = 228 + Left = 220 Height = 25 Top = 97 Width = 62 Anchors = [akTop, akRight] AutoSize = True + BorderSpacing.Left = 16 BorderSpacing.Top = 8 BorderSpacing.Right = 12 BorderSpacing.Bottom = 8 @@ -108,17 +111,18 @@ object ExpSmoothFrm: TExpSmoothFrm AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - Left = 302 + Left = 294 Height = 25 Top = 97 Width = 42 Anchors = [akTop, akRight] AutoSize = True BorderSpacing.Top = 8 - BorderSpacing.Right = 8 + BorderSpacing.Right = 16 BorderSpacing.Bottom = 8 Caption = 'OK' ModalResult = 1 + OnClick = OKBtnClick TabOrder = 3 end object Bevel1: TBevel diff --git a/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.pas b/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.pas index 16d4eef05..cea7f4ff5 100644 --- a/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/expsmoothunit.pas @@ -23,13 +23,15 @@ type AlphaScroll: TScrollBar; procedure AlphaScrollChange(Sender: TObject); procedure FormActivate(Sender: TObject); - procedure FormShow(Sender: TObject); + procedure OKBtnClick(Sender: TObject); private { private declarations } + FAlpha: Double; + procedure SetAlpha(AValue: Double); public { public declarations } - alpha : double; - end; + property Alpha: Double read FAlpha write SetAlpha; + end; var ExpSmoothFrm: TExpSmoothFrm; @@ -47,17 +49,34 @@ begin CancelBtn.Constraints.MinWidth := OKBtn.Constraints.MinWidth; end; -procedure TExpSmoothFrm.FormShow(Sender: TObject); +procedure TExpSmoothFrm.OKBtnClick(Sender: TObject); begin - AlphaEdit.Text := '0.99'; - AlphaScroll.Position := 99; - alpha := 0.99; + if AlphaEdit.Text = '' then + begin + AlphaEdit.SetFocus; + MessageDlg('Alpha cannot be empty.', mtError, [mbOK], 0); + ModalResult := mrNone; + end else + if not TryStrToFloat(AlphaEdit.Text, FAlpha) or (FAlpha < 0.0) or (FAlpha > 1.0) then + begin + AlphaEdit.SetFocus; + MessageDlg('Alpha must be > 0 and < 1', mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + +procedure TExpSmoothFrm.SetAlpha(AValue: Double); +begin + if (AValue = FAlpha) then exit; + FAlpha := AValue; + AlphaScroll.Position := Round(100 * FAlpha); + AlphaEdit.Text := FormatFloat('0.00', FAlpha); end; procedure TExpSmoothFrm.AlphaScrollChange(Sender: TObject); begin - AlphaEdit.Text := FloatToStr(AlphaScroll.Position / 100.0); - alpha := AlphaScroll.Position / 100.0; + FAlpha := AlphaScroll.Position / 100.0; + AlphaEdit.Text := FormatFloat('0.00', FAlpha); end; diff --git a/applications/lazstats/source/forms/analysis/correlation/fftunit.lfm b/applications/lazstats/source/forms/analysis/correlation/fftunit.lfm index 2f15ef442..5fa20f57e 100644 --- a/applications/lazstats/source/forms/analysis/correlation/fftunit.lfm +++ b/applications/lazstats/source/forms/analysis/correlation/fftunit.lfm @@ -2,11 +2,11 @@ object FFTFrm: TFFTFrm Left = 648 Height = 127 Top = 346 - Width = 305 + Width = 224 BorderStyle = bsDialog Caption = 'Fourier Transform Form' ClientHeight = 127 - ClientWidth = 305 + ClientWidth = 224 OnActivate = FormActivate Position = poMainFormCenter LCLVersion = '2.1.0.0' @@ -14,7 +14,7 @@ object FFTFrm: TFFTFrm AnchorSideTop.Control = Bevel1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = OKBtn - Left = 177 + Left = 96 Height = 25 Top = 93 Width = 62 @@ -32,7 +32,7 @@ object FFTFrm: TFFTFrm AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom - Left = 251 + Left = 170 Height = 25 Top = 93 Width = 42 @@ -43,6 +43,7 @@ object FFTFrm: TFFTFrm BorderSpacing.Bottom = 8 Caption = 'OK' ModalResult = 1 + OnClick = OKBtnClick TabOrder = 2 end object Memo1: TLabel @@ -53,7 +54,7 @@ object FFTFrm: TFFTFrm Left = 8 Height = 30 Top = 8 - Width = 289 + Width = 208 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 8 BorderSpacing.Top = 8 @@ -64,17 +65,16 @@ object FFTFrm: TFFTFrm end object Panel1: TPanel AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = Memo1 AnchorSideTop.Side = asrBottom - Left = 66 + Left = 24 Height = 23 Top = 50 Width = 172 AutoSize = True - BorderSpacing.Left = 64 + BorderSpacing.Left = 24 BorderSpacing.Top = 12 - BorderSpacing.Right = 64 + BorderSpacing.Right = 24 BorderSpacing.Bottom = 4 BevelOuter = bvNone ClientHeight = 23 @@ -115,7 +115,7 @@ object FFTFrm: TFFTFrm Left = 0 Height = 8 Top = 77 - Width = 305 + Width = 224 Anchors = [akTop, akLeft, akRight] Shape = bsBottomLine end diff --git a/applications/lazstats/source/forms/analysis/correlation/fftunit.pas b/applications/lazstats/source/forms/analysis/correlation/fftunit.pas index 257731a3a..ab7ec09c3 100644 --- a/applications/lazstats/source/forms/analysis/correlation/fftunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/fftunit.pas @@ -21,6 +21,7 @@ type Label1: TLabel; Panel1: TPanel; procedure FormActivate(Sender: TObject); + procedure OKBtnClick(Sender: TObject); private { private declarations } public @@ -46,6 +47,24 @@ begin OKBtn.Constraints.MinWidth := w; end; +procedure TFFTFrm.OKBtnClick(Sender: TObject); +var + n: Integer; +begin + if NptsEdit.Text = '' then + begin + NptsEdit.SetFocus; + MessageDlg('Number of points not specified.', mtError, [mbOK], 0); + ModalResult := mrNone; + end else + if not TryStrToInt(NptsEdit.Text, n) or (n <= 0) then + begin + NptsEdit.SetFocus; + MessageDlg('Number of points must be a valid and positive integer.', mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + initialization {$I fftunit.lrs} diff --git a/applications/lazstats/source/forms/analysis/correlation/moveavgunit.lfm b/applications/lazstats/source/forms/analysis/correlation/moveavgunit.lfm index 08795a0d7..a2b02ac03 100644 --- a/applications/lazstats/source/forms/analysis/correlation/moveavgunit.lfm +++ b/applications/lazstats/source/forms/analysis/correlation/moveavgunit.lfm @@ -1,11 +1,12 @@ object MoveAvgFrm: TMoveAvgFrm Left = 434 - Height = 307 + Height = 292 Top = 163 Width = 372 Caption = 'Moving Average Specification Form' - ClientHeight = 307 + ClientHeight = 292 ClientWidth = 372 + OnActivate = FormActivate OnShow = FormShow Position = poMainFormCenter LCLVersion = '2.1.0.0' @@ -43,7 +44,7 @@ object MoveAvgFrm: TMoveAvgFrm Top = 13 Width = 118 Alignment = taRightJustify - OnKeyPress = OrderEditKeyPress + OnEditingDone = OrderEditEditingDone TabOrder = 0 Text = 'OrderEdit' end @@ -58,19 +59,18 @@ object MoveAvgFrm: TMoveAvgFrm Width = 118 Alignment = taRightJustify BorderSpacing.Left = 8 - OnKeyPress = ThetaEditKeyPress TabOrder = 1 Text = 'ThetaEdit' end object ThetaList: TListBox AnchorSideLeft.Control = Owner - AnchorSideRight.Control = Panel1 - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = OKBtn Left = 8 - Height = 219 + Height = 171 Top = 80 - Width = 286 + Width = 356 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Left = 8 BorderSpacing.Right = 8 @@ -79,76 +79,79 @@ object MoveAvgFrm: TMoveAvgFrm OnClick = ThetaListClick TabOrder = 2 end - object Panel1: TPanel + object OKBtn: TButton AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 302 - Height = 157 - Top = 142 - Width = 62 + Left = 322 + Height = 25 + Top = 259 + Width = 42 Anchors = [akRight, akBottom] AutoSize = True - BorderSpacing.Top = 8 BorderSpacing.Right = 8 BorderSpacing.Bottom = 8 - BevelOuter = bvNone - ChildSizing.VerticalSpacing = 8 - ChildSizing.Layout = cclLeftToRightThenTopToBottom - ClientHeight = 157 - ClientWidth = 62 + Caption = 'OK' + ModalResult = 1 + OnClick = OKBtnClick TabOrder = 3 - object HelpBtn: TButton - Tag = 132 - Left = 0 - Height = 25 - Top = 0 - Width = 62 - AutoSize = True - Caption = 'Help' - OnClick = HelpBtnClick - TabOrder = 0 - end - object ResetBtn: TButton - Left = 0 - Height = 25 - Top = 33 - Width = 62 - AutoSize = True - Caption = 'Reset' - OnClick = ResetBtnClick - TabOrder = 1 - end - object CancelBtn: TButton - Left = 0 - Height = 25 - Top = 66 - Width = 62 - AutoSize = True - Caption = 'Cancel' - ModalResult = 2 - TabOrder = 2 - end - object ApplyBtn: TButton - Left = 0 - Height = 25 - Top = 99 - Width = 62 - AutoSize = True - Caption = 'Apply' - OnClick = ApplyBtnClick - TabOrder = 3 - end - object OKBtn: TButton - Left = 0 - Height = 25 - Top = 132 - Width = 62 - AutoSize = True - Caption = 'OK' - ModalResult = 1 - TabOrder = 4 - end + end + object CancelBtn: TButton + AnchorSideTop.Control = OKBtn + AnchorSideRight.Control = OKBtn + Left = 252 + Height = 25 + Top = 259 + Width = 62 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Right = 8 + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 4 + end + object ApplyBtn: TButton + AnchorSideTop.Control = OKBtn + AnchorSideRight.Control = CancelBtn + Left = 187 + Height = 25 + Top = 259 + Width = 57 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Right = 8 + Caption = 'Apply' + OnClick = ApplyBtnClick + TabOrder = 5 + end + object ResetBtn: TButton + AnchorSideTop.Control = OKBtn + AnchorSideRight.Control = ApplyBtn + Left = 125 + Height = 25 + Top = 259 + Width = 54 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Right = 8 + Caption = 'Reset' + OnClick = ResetBtnClick + TabOrder = 6 + end + object HelpBtn: TButton + Tag = 132 + AnchorSideTop.Control = OKBtn + AnchorSideRight.Control = ResetBtn + Left = 66 + Height = 25 + Top = 259 + Width = 51 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Right = 8 + Caption = 'Help' + OnClick = HelpBtnClick + TabOrder = 7 end end diff --git a/applications/lazstats/source/forms/analysis/correlation/moveavgunit.pas b/applications/lazstats/source/forms/analysis/correlation/moveavgunit.pas index 19cfa75df..b52252d86 100644 --- a/applications/lazstats/source/forms/analysis/correlation/moveavgunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/moveavgunit.pas @@ -15,7 +15,6 @@ type TMoveAvgFrm = class(TForm) HelpBtn: TButton; - Panel1: TPanel; ResetBtn: TButton; CancelBtn: TButton; ApplyBtn: TButton; @@ -26,17 +25,20 @@ type OrderEdit: TEdit; Label1: TLabel; procedure ApplyBtnClick(Sender: TObject); + procedure FormActivate(Sender: TObject); procedure FormShow(Sender: TObject); procedure HelpBtnClick(Sender: TObject); - procedure OrderEditKeyPress(Sender: TObject; var Key: char); + procedure OKBtnClick(Sender: TObject); + procedure OrderEditEditingDone(Sender: TObject); procedure ResetBtnClick(Sender: TObject); - procedure ThetaEditKeyPress(Sender: TObject; var Key: char); + procedure ThetaEditEditingDone(Sender: TObject); procedure ThetaListClick(Sender: TObject); private { private declarations } + function Validate(out AMsg: String; out AControl: TWinControl): Boolean; public { public declarations } - W : array[0..20] of double; + W: array[0..20] of double; order : integer; currentindex : integer; @@ -47,42 +49,59 @@ var implementation +uses + Math; + { TMoveAvgFrm } procedure TMoveAvgFrm.ResetBtnClick(Sender: TObject); -VAR i : integer; +var + i: integer; begin - OrderEdit.Text := ''; - ThetaEdit.Text := ''; - ThetaList.Clear; - currentindex := 0; - for i := 0 to 20 do W[i] := 1.0; + OrderEdit.Text := ''; + ThetaEdit.Text := ''; + ThetaList.Clear; + CurrentIndex := 0; + for i := 0 to 20 do W[i] := 1.0; end; +procedure TMoveAvgFrm.ThetaEditEditingDone(Sender: TObject); +var + cellString: String; +begin + if CurrentIndex < 1 then + exit; + cellString := Format('Theta(%d) = %s', [currentIndex + 1, ThetaEdit.Text]); + ThetaList.Items[CurrentIndex] := cellString; + W[currentIndex + 1] := StrToFloat(ThetaEdit.Text); +end; + (* procedure TMoveAvgFrm.ThetaEditKeyPress(Sender: TObject; var Key: char); -var cellstring : string; - +var + cellstring: string; begin - if currentindex < 1 then exit; - if ord(Key) <> 13 then exit; - cellstring := 'Theta(' + IntToStr(currentindex + 1) + ') = '; - cellstring := cellstring + ThetaEdit.Text; - W[currentindex + 1] := StrToFloat(ThetaEdit.Text); -end; + if currentindex < 1 then exit; + if ord(Key) <> 13 then exit; + cellstring := 'Theta(' + IntToStr(currentindex + 1) + ') = ' + ThetaEdit.Text; + W[currentindex + 1] := StrToFloat(ThetaEdit.Text); +end; *) procedure TMoveAvgFrm.ThetaListClick(Sender: TObject); -VAR index : integer; +var + index: integer; begin - index := ThetaList.ItemIndex; - if index < 0 then exit; + index := ThetaList.ItemIndex; + if index >= 0 then + begin currentindex := index; ThetaEdit.Text := '1.0'; ThetaEdit.SetFocus; + end; end; procedure TMoveAvgFrm.FormShow(Sender: TObject); begin - ResetBtnClick(self); + ResetBtnClick(self); end; procedure TMoveAvgFrm.HelpBtnClick(Sender: TObject); @@ -92,38 +111,108 @@ begin ContextHelpForm.HelpMessage((Sender as TButton).tag); end; -procedure TMoveAvgFrm.ApplyBtnClick(Sender: TObject); +procedure TMoveAvgFrm.OKBtnClick(Sender: TObject); var - sum : double; - i : integer; - cellstring : string; - + msg: String; + C: TWinControl; begin - ThetaList.Clear; - sum := W[0]; - for i := 1 to order do sum := sum + (2.0 * W[i]); - for i := 0 to order do - begin - W[i] := W[i] / sum; - cellstring := 'Theta(' + IntToStr(i+1) + ') = '; - cellstring := cellstring + FloatToStr(W[i]); - ThetaList.Items.Add(cellstring); - end; + if not Validate(msg, C) then + begin + C.SetFocus; + MessageDlg(msg, mtError, [mbOK], 0); + ModalResult := mrNone; + end; end; -procedure TMoveAvgFrm.OrderEditKeyPress(Sender: TObject; var Key: char); -VAR cellstring : string; - i : integer; - +procedure TMoveAvgFrm.ApplyBtnClick(Sender: TObject); +var + sum: double; + i: integer; + cellstring: string; begin - if ord(Key) <> 13 then exit; + ThetaList.Clear; + sum := W[0]; + for i := 1 to order do + sum := sum + 2.0 * W[i]; + for i := 0 to order do + begin + W[i] := W[i] / sum; + cellstring := 'Theta(' + IntToStr(i+1) + ') = ' + FloatToStr(W[i]); + ThetaList.Items.Add(cellstring); + end; +end; + +procedure TMoveAvgFrm.FormActivate(Sender: TObject); +var + wid: Integer; +begin + wid := MaxValue([HelpBtn.Width, ResetBtn.Width, ApplyBtn.Width, CancelBtn.Width, OKBtn.Width]); + HelpBtn.Constraints.MinWidth := wid; + ResetBtn.Constraints.MinWidth := wid; + ApplyBtn.Constraints.MinWidth := wid; + CancelBtn.Constraints.MinWidth := wid; + OKBtn.Constraints.MinWidth := wid; +end; + +procedure TMoveAvgFrm.OrderEditEditingDone(Sender: TObject); +var + i: Integer; +begin + ThetaList.Items.BeginUpdate; + try ThetaList.Clear; - order := StrToInt(OrderEdit.Text); - for i := 1 to order do - begin - cellstring := 'Theta(' + IntToStr(i) + ')'; - ThetaList.Items.Add(cellstring); - end; + Order := StrToInt(orderEdit.Text); + for i := 1 to Order do + ThetaList.Items.Add('Theta(' + IntToStr(i) + ')'); + finally + ThetaList.Items.EndUpdate; + end; +end; + + (* +procedure TMoveAvgFrm.OrderEditKeyPress(Sender: TObject; var Key: char); +var + cellstring: string; + i: integer; +begin + if ord(Key) <> 13 then exit; + ThetaList.Clear; + order := StrToInt(OrderEdit.Text); + for i := 1 to order do + begin + cellstring := 'Theta(' + IntToStr(i) + ')'; + ThetaList.Items.Add(cellstring); + end; +end; +*) + +function TMoveAvgFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; +var + n: Integer; +begin + Result := false; + + if OrderEdit.Text = '' then + begin + AControl := OrderEdit; + AMsg := 'Input required.'; + exit; + end; + if not TryStrToInt(OrderEdit.Text, n) or (n < 0) then + begin + AControl := OrderEdit; + AMsg := 'Non-negative integer value required.'; + exit; + end; + + if ThetaEdit.Text <> '' then + begin + AControl := ThetaEdit; + AMsg := 'Please press ENTER to add this input.'; + exit; + end; + + Result := true; end; initialization diff --git a/applications/lazstats/source/forms/analysis/correlation/polynomialunit.lfm b/applications/lazstats/source/forms/analysis/correlation/polynomialunit.lfm index d1c6d62e3..49b790193 100644 --- a/applications/lazstats/source/forms/analysis/correlation/polynomialunit.lfm +++ b/applications/lazstats/source/forms/analysis/correlation/polynomialunit.lfm @@ -45,6 +45,7 @@ object PolynomialFrm: TPolynomialFrm BorderSpacing.Bottom = 8 Caption = 'OK' ModalResult = 1 + OnClick = OKBtnClick TabOrder = 3 end object HelpBtn: TButton diff --git a/applications/lazstats/source/forms/analysis/correlation/polynomialunit.pas b/applications/lazstats/source/forms/analysis/correlation/polynomialunit.pas index a31179c84..bd73bf57f 100644 --- a/applications/lazstats/source/forms/analysis/correlation/polynomialunit.pas +++ b/applications/lazstats/source/forms/analysis/correlation/polynomialunit.pas @@ -24,6 +24,7 @@ type procedure FormActivate(Sender: TObject); procedure FormShow(Sender: TObject); procedure HelpBtnClick(Sender: TObject); + procedure OKBtnClick(Sender: TObject); private { private declarations } public @@ -62,6 +63,24 @@ begin ContextHelpForm.HelpMessage((Sender as TButton).tag); end; +procedure TPolynomialFrm.OKBtnClick(Sender: TObject); +var + n: Integer; +begin + if PolyEdit.Text = '' then + begin + PolyEdit.SetFocus; + MessageDlg('Polynomial order not specified.', mtError, [mbOK], 0); + ModalResult := mrNone; + end else + if not TryStrToInt(PolyEdit.Text, n) or (n < 0) then + begin + PolyEdit.SetFocus; + MessageDlg('Polynomial order must be a valid integer > 0', mtError, [mbOK], 0); + ModalResult := mrNone; + end; +end; + initialization {$I polynomialunit.lrs} diff --git a/applications/lazstats/source/forms/misc/outputunit.pas b/applications/lazstats/source/forms/misc/outputunit.pas index f6f9972b6..5afb11458 100644 --- a/applications/lazstats/source/forms/misc/outputunit.pas +++ b/applications/lazstats/source/forms/misc/outputunit.pas @@ -63,12 +63,15 @@ const procedure DisplayReport(AReport: TStrings); begin - if OutputFrm = nil then - OutputFrm := TOutputFrm.Create(Application) - else - OutputFrm.Clear; - OutputFrm.AddLines(AReport); - OutputFrm.ShowModal; + if AReport.Count > 0 then + begin + if OutputFrm = nil then + OutputFrm := TOutputFrm.Create(Application) + else + OutputFrm.Clear; + OutputFrm.AddLines(AReport); + OutputFrm.ShowModal; + end; end; diff --git a/applications/lazstats/source/units/globals.pas b/applications/lazstats/source/units/globals.pas index 8674474b3..3a63e3e72 100644 --- a/applications/lazstats/source/units/globals.pas +++ b/applications/lazstats/source/units/globals.pas @@ -89,11 +89,14 @@ const ); DIVIDER = '==========================================================================='; + DIVIDER_SMALL = '---------------------------------------------------------------------------'; GRAPH_BACK_COLOR = clCream; GRAPH_WALL_COLOR = clGray; GRAPH_FLOOR_COLOR = clLtGray; + TWO_PI = 2.0 * PI; + implementation end.