![]() |
Statistics for MySQL
0.9
|
00001 /* skewness_pop.c (population moment coefficient of skewness) */ 00002 00003 /*********************************************************************** 00004 * This code is part of Statistics for MySQL. 00005 * 00006 * Copyright (C) 2011 Heinrich Schuchardt (xypron.glpk@gmx.de) 00007 * 00008 * Licensed under the Apache License, Version 2.0 (the "License"); 00009 * you may not use this file except in compliance with the License. 00010 * You may obtain a copy of the License at 00011 * 00012 * http://www.apache.org/licenses/LICENSE-2.0 00013 * 00014 * Unless required by applicable law or agreed to in writing, software 00015 * distributed under the License is distributed on an "AS IS" BASIS, 00016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00017 * See the License for the specific language governing permissions and 00018 * limitations under the License. 00019 ***********************************************************************/ 00020 00030 #include "sqlstat.h" 00031 00035 struct skewness_pop_storage { 00036 int argc; 00037 double count; 00038 double sumX; 00039 double sumXX; 00040 double sumXXX; 00041 }; 00042 00055 my_bool skewness_pop_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { 00056 struct skewness_pop_storage * data; 00057 00058 if (args->arg_count < 1 || args->arg_count > 2) { 00059 strcpy(message,"skewness_pop() requires one or two arguments"); 00060 return 1; 00061 } 00062 args->arg_type[0] = REAL_RESULT; 00063 if (args->arg_count > 1) { 00064 args->arg_type[1] = REAL_RESULT; 00065 } 00066 00067 data = (struct skewness_pop_storage *) malloc( sizeof(struct skewness_pop_storage)); 00068 if (data == NULL) { 00069 strcpy(message,"Couldn't allocate memory"); 00070 return 1; 00071 } 00072 data->argc = args->arg_count; 00073 00074 initid->maybe_null = 1; 00075 initid->decimals = NOT_FIXED_DEC; 00076 initid->max_length = 13 + initid->decimals; 00077 initid->ptr = (char *) data; 00078 initid->const_item = 0; 00079 00080 return 0; 00081 } 00082 00094 void skewness_pop_reset(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00095 skewness_pop_clear(initid, is_null, error); 00096 skewness_pop_add(initid, args, is_null, error); 00097 } 00098 00108 void skewness_pop_clear(UDF_INIT *initid, char *is_null, char *error) { 00109 struct skewness_pop_storage *data; 00110 data = (struct skewness_pop_storage *) initid->ptr; 00111 data->count = 0; 00112 data->sumX = 0; 00113 data->sumXX = 0; 00114 data->sumXXX = 0; 00115 } 00116 00127 void skewness_pop_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00128 struct skewness_pop_storage * data; 00129 double x; 00130 double w; 00131 00132 if (!args->args[0]) { 00133 return; 00134 } 00135 data = (struct skewness_pop_storage *) initid->ptr; 00136 if (data->argc > 1) { 00137 if (!args->args[1]) { 00138 return; 00139 } 00140 w = *((double*) args->args[1]); 00141 } else { 00142 w = 1.; 00143 } 00144 x = *((double*) args->args[0]); 00145 00146 data->count += w; 00147 data->sumX += w * x; 00148 data->sumXX += w * x*x; 00149 data->sumXXX += w * x*x*x; 00150 } 00151 00161 double skewness_pop(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { 00162 struct skewness_pop_storage * data; 00163 double m3; 00164 double m2; 00165 double mean; 00166 00167 double ret; 00168 00169 data = (struct skewness_pop_storage *) initid->ptr; 00170 00171 if (data->count <= 0) { 00172 *is_null = 1; 00173 return 0; 00174 } 00175 00176 mean = data->sumX / data->count; 00177 00178 m3 = (data->sumXXX - 3 * mean * data->sumXX + 2 * mean * mean * data->sumX) / data->count; 00179 m2 = (data->sumXX - mean * data->sumX) / data->count; 00180 00181 if (m2 <= 0) { 00182 *is_null = 1; 00183 return 0; 00184 } 00185 00186 ret = m3 / sqrt(m2 * m2 * m2); 00187 00188 return ret; 00189 } 00190 00198 void skewness_pop_deinit(UDF_INIT *initid) { 00199 if (initid->ptr) { 00200 free(initid->ptr); 00201 } 00202 }