Created
April 30, 2012 06:03
-
-
Save JaHIY/2555881 to your computer and use it in GitHub Desktop.
C: Grubbs, 4d, Q (rewrite gist:2145652[python] into C Language)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<stdio.h> | |
#include<stdlib.h> | |
#include<string.h> | |
#include<math.h> | |
/* | |
1.Grubbs | |
./svalues 1.25 1.27 1.31 1.40 1.40 0.05 Grubbs | |
./svalues data(0) data(1) data(2) ... data(n) (n>=2) 可疑值x 显著性水平a(可用值为 0.05/0.025/0.01) Grubbs | |
2.4d | |
./svalues 1.25 1.27 1.31 1.40 1.40 4d | |
./svalues data(0) data(1) data(2) ... data(n) (n>=2) 可疑值x 4d | |
3.Q | |
./svalues 1.25 1.27 1.31 1.40 1.40 0.90 Q | |
./svalues data(0) data(1) data(2) ... data(n) (n>=2) 可疑值x 置信度t(可用值为 0.90/0.96/0.99) Q | |
*/ | |
struct RS { | |
double a; | |
int b; | |
}; | |
int A_dict(const char *a) { | |
if (strcmp(a, "0.05") == 0) { | |
return 0; | |
} else if (strcmp(a, "0.025") == 0) { | |
return 1; | |
} else if (strcmp(a, "0.01") == 0 ) { | |
return 2; | |
} else { | |
return -1; | |
} | |
} | |
double T_list (int n, int a) { | |
const double T[][3] = {{1.15, 1.15, 1.15}, {1.46, 1.48, 1.49}, {1.67, 1.71, 1.75}, {1.82, 1.89, 1.94}, {1.94, 2.02, 2.10}, {2.03, 2.13, 2.22}, {2.11, 2.21, 2.32}, {2.18, 2.29, 2.41}, {2.23, 2.36, 2.48}, {2.29, 2.41, 2.55}, {2.33, 2.46, 2.61}, {2.37, 2.51, 2.63}, {2.41, 2.55, 2.71}, {2.56, 2.71, 2.88}}; | |
return T[n][a]; | |
} | |
int cmp(const void *a , const void *b) { | |
return *(double *)a > *(double *)b ? 1 : -1; | |
} | |
double sum(const double *data, int n) { | |
double sum = 0.0; | |
int i; | |
for(i=0;i<n;i++) { | |
sum += data[i]; | |
} | |
return sum; | |
} | |
double *avg_std(const double *data, int n) { | |
double *result = NULL, tmp = 0.0; | |
int i; | |
result = (double *)calloc(2, sizeof(double)); | |
*result = sum(data, n)/((double) n); | |
for(i=0;i<n;i++) { | |
tmp += pow(*(data+i)-*result, 2); | |
} | |
*(result+1) = sqrt(tmp/((double) n)); | |
return result; | |
} | |
int count(const double *data, int n, double x) { | |
int i, j=0; | |
for(i=0;i<n;i++) { | |
if (*(data+i) == x) { | |
j++; | |
} | |
} | |
return j; | |
} | |
double *del_array(const double *data, int n, double x) { | |
int i, j = count(data, n, x); | |
double *p; | |
p = (double *)calloc(n-j, sizeof(double)); | |
for(i=0,j=0;i<n-j;i++) { | |
if (x == *(data+j)) { | |
*(p+i) = *(data+(++j)); | |
} else { | |
*(p+i) = *(data+j); | |
} | |
j++; | |
} | |
return p; | |
} | |
int T_dict(const char *t) { | |
if (strcmp(t, "0.90") == 0) | |
return 0; | |
else if (strcmp(t, "0.96") == 0) | |
return 1; | |
else if (strcmp(t, "0.99") == 0) | |
return 2; | |
else | |
return -1; | |
} | |
int b_search(const double *array, int low_index, int high_index, double key) { | |
if (low_index > high_index) | |
return -1; | |
else { | |
int mid = (low_index+high_index)/2; | |
if (key == *(array+mid)) | |
return mid; | |
else if (key < *(array+mid)) | |
return b_search(array, low_index, mid-1, key); | |
else | |
return b_search(array, mid+1, high_index, key); | |
} | |
} | |
double Q_list(int n, int t) { | |
const double Q[][3] = {{0.94, 0.98, 0.99}, {0.76, 0.85, 0.93}, {0.64, 0.73, 0.82}, {0.56, 0.64, 0.74}, {0.51, 0.59, 0.68}, {0.47, 0.54, 0.63}, {0.44, 0.51, 0.60}, {0.41, 0.48, 0.57}}; | |
return Q[n][t]; | |
} | |
struct RS *_q(int n, double *data, const char *a, double x) { | |
struct RS *result = NULL; | |
int i; | |
result = (struct RS *)calloc(1, sizeof(struct RS)); | |
qsort(data, n, sizeof(data[0]), cmp); | |
i = b_search(data, 0, n-1, x); | |
result->a = ((i == 0) ? (*(data+1)-(*data)) : (*(data+i)-(*(data+i-1))))/(*(data+n-1)-(*data)); | |
result->b = (result->a > Q_list(n-3, T_dict(a))) ? 0 : 1; | |
return result; | |
} | |
struct RS *grubbs(int n, double *data, const char *t, double x) { | |
double *as = avg_std(data, n), tmp; | |
struct RS *result; | |
result = (struct RS *)calloc(1, sizeof(struct RS)); | |
qsort(data, n, sizeof(data[0]), cmp); | |
tmp = (x-(*as))/(*(as+1)); | |
tmp = (x == *data) && (-1)*tmp; | |
result->a = T_list(n-3, A_dict(t)); | |
result->b = (tmp > result->a) ? 0 : 1; | |
free(as); | |
as = NULL; | |
return result; | |
} | |
struct RS *_4d(int n, const double *data, double x) { | |
double *p = NULL, *as = NULL; | |
struct RS *result; | |
int j; | |
result = (struct RS *)calloc(1, sizeof(struct RS)); | |
j = n - count(data, n, x); | |
p = del_array(data, n, x); | |
as = avg_std(p, j); | |
result->a = fabs(x-(*as)); | |
result->b = (result->a > 4*(*(as+1))) ? 0 : 1; | |
free(as); | |
as = NULL; | |
free(p); | |
p = NULL; | |
return result; | |
} | |
int main(int argc, char *argv[]) { | |
int i; | |
double *data = NULL; | |
struct RS *result = NULL; | |
if ((strcmp(argv[argc-1], "Grubbs") && (strcmp(argv[argc-1], "Q"))) == 0) { | |
data = (double *)calloc(argc-4, sizeof(double)); | |
for(i=0;i<argc-4;i++) { | |
puts(argv[i+1]); | |
*(data+i) = atof(argv[i+1]); | |
} | |
if (strcmp(argv[argc-1], "Q") == 0) { | |
result = _q(argc-4, data, argv[argc-2], atof(argv[argc-3])); | |
printf("Q = %.5f, You should %s %.5f (Q)\n", result->a, (result->b == 0) ? "Delete" : "Retain", atof(argv[argc-3])); | |
} else { | |
result = grubbs(argc-4, data, argv[argc-2], atof(argv[argc-3])); | |
printf("T = %.5f, You should %s %.5f (Grubbs)\n", result->a, (result->b == 0) ? "Delete" : "Retain", atof(argv[argc-3])); | |
} | |
} else if (strcmp(argv[argc-1], "4d") == 0) { | |
data = (double *)calloc(argc-3, sizeof(double)); | |
for(i=0;i<argc-3;i++) { | |
puts(argv[i+1]); | |
*(data+i) = atof(argv[i+1]); | |
} | |
result = _4d(argc-3, data, atof(argv[argc-2])); | |
printf("Delta = %.5f, You should %s %.5f (4d)\n", result->a, (result->b == 0) ? "Delete" : "Retain", atof(argv[argc-2])); | |
} else { | |
printf("Error!\n"); | |
} | |
free(data); | |
data = NULL; | |
free(result); | |
result = NULL; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment