JWS C Library
C language utility library
|
00001 /* 00002 * This work is licensed under a Creative Commons 00003 * Attribution-Noncommercial-Share Alike 3.0 United States License. 00004 * 00005 * http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 00006 * 00007 * You are free: 00008 * 00009 * to Share - to copy, distribute, display, and perform the work 00010 * to Remix - to make derivative works 00011 * 00012 * Under the following conditions: 00013 * 00014 * Attribution. You must attribute the work in the manner specified by the 00015 * author or licensor (but not in any way that suggests that they endorse you 00016 * or your use of the work). 00017 * 00018 * Noncommercial. You may not use this work for commercial purposes. 00019 * 00020 * Share Alike. If you alter, transform, or build upon this work, you may 00021 * distribute the resulting work only under the same or similar license to 00022 * this one. 00023 * 00024 * For any reuse or distribution, you must make clear to others the license 00025 * terms of this work. The best way to do this is by including this header. 00026 * 00027 * Any of the above conditions can be waived if you get permission from the 00028 * copyright holder. 00029 * 00030 * Apart from the remix rights granted under this license, nothing in this 00031 * license impairs or restricts the author's moral rights. 00032 */ 00033 00034 00046 #include <jwsc/config.h> 00047 00048 #include <stdlib.h> 00049 #include <math.h> 00050 #include <inttypes.h> 00051 00052 #include "jwsc/base/error.h" 00053 #include "jwsc/vector/vector.h" 00054 #include "jwsc/vector/vector_math.h" 00055 #include "jwsc/matrix/matrix.h" 00056 #include "jwsc/matrix/matrix_math.h" 00057 #include "jwsc/stat/stat.h" 00058 00059 00071 void sample_mean_f(float* mean_out, const Vector_f* x) 00072 { 00073 uint32_t n, N; 00074 float sum; 00075 00076 N = x->num_elts; 00077 sum = 0; 00078 00079 for (n = 0; n < N; n++) 00080 { 00081 sum += x->elts[ n ]; 00082 } 00083 00084 *mean_out = sum / (float)N; 00085 } 00086 00091 void sample_mean_d(double* mean_out, const Vector_d* x) 00092 { 00093 uint32_t n, N; 00094 double sum; 00095 00096 N = x->num_elts; 00097 sum = 0; 00098 00099 for (n = 0; n < N; n++) 00100 { 00101 sum += x->elts[ n ]; 00102 } 00103 00104 *mean_out = sum / (double)N; 00105 } 00106 00121 void sample_variance_f(float* var_out, const Vector_f* x) 00122 { 00123 uint32_t n, N; 00124 float sum, ssum; 00125 00126 N = x->num_elts; 00127 sum = 0; 00128 ssum = 0; 00129 00130 for (n = 0; n < N; n++) 00131 { 00132 sum += x->elts[ n ]; 00133 ssum += x->elts[ n ] * x->elts[ n ]; 00134 } 00135 00136 if (N > 1) 00137 { 00138 *var_out = (1.0 / (float)(N-1)) * (ssum - ((sum*sum) / (float)N)); 00139 } 00140 else 00141 { 00142 *var_out = ssum - sum*sum; 00143 } 00144 } 00145 00150 void sample_variance_d(double* var_out, const Vector_d* x) 00151 { 00152 uint32_t n, N; 00153 double sum, ssum; 00154 00155 N = x->num_elts; 00156 sum = 0; 00157 ssum = 0; 00158 00159 for (n = 0; n < N; n++) 00160 { 00161 sum += x->elts[ n ]; 00162 ssum += x->elts[ n ] * x->elts[ n ]; 00163 } 00164 00165 if (N > 1) 00166 { 00167 *var_out = (1.0 / (double)(N-1)) * (ssum - ((sum*sum) / (double)N)); 00168 } 00169 else 00170 { 00171 *var_out = ssum - sum*sum; 00172 } 00173 } 00174 00189 void sample_error_f(float* err_out, const Vector_f* x) 00190 { 00191 float var; 00192 00193 sample_variance_f(&var, x); 00194 00195 *err_out = sqrt(var / (float)(x->num_elts)); 00196 } 00197 00202 void sample_error_d(double* err_out, const Vector_d* x) 00203 { 00204 double var; 00205 00206 sample_variance_d(&var, x); 00207 00208 *err_out = sqrt(var / (double)(x->num_elts)); 00209 } 00210 00227 void sample_stats_f 00228 ( 00229 float* mean_out, 00230 float* var_out, 00231 float* err_out, 00232 const Vector_f* x 00233 ) 00234 { 00235 uint32_t n, N; 00236 float sum, ssum; 00237 00238 N = x->num_elts; 00239 sum = 0; 00240 ssum = 0; 00241 00242 for (n = 0; n < N; n++) 00243 { 00244 sum += x->elts[ n ]; 00245 ssum += x->elts[ n ] * x->elts[ n ]; 00246 } 00247 00248 *mean_out = sum / (float)N; 00249 00250 if (N > 1) 00251 { 00252 *var_out = (1.0 / (float)(N-1)) * (ssum - ((sum*sum) / (float)N)); 00253 } 00254 else 00255 { 00256 *var_out = ssum - sum*sum; 00257 } 00258 00259 *err_out = sqrt(*var_out / (float)N); 00260 } 00261 00268 void sample_stats_d 00269 ( 00270 double* mean_out, 00271 double* var_out, 00272 double* err_out, 00273 const Vector_d* x 00274 ) 00275 { 00276 uint32_t n, N; 00277 double sum, ssum; 00278 00279 N = x->num_elts; 00280 sum = 0; 00281 ssum = 0; 00282 00283 for (n = 0; n < N; n++) 00284 { 00285 sum += x->elts[ n ]; 00286 ssum += x->elts[ n ] * x->elts[ n ]; 00287 } 00288 00289 *mean_out = sum / (double)N; 00290 00291 if (N > 1) 00292 { 00293 *var_out = (1.0 / (double)(N-1)) * (ssum - ((sum*sum) / (double)N)); 00294 } 00295 else 00296 { 00297 *var_out = ssum - sum*sum; 00298 } 00299 00300 *err_out = sqrt(*var_out / (double)N); 00301 } 00302 00320 void ind_mv_sample_stats_f 00321 ( 00322 Vector_f** means_out, 00323 Vector_f** vars_out, 00324 Vector_f** errs_out, 00325 const Matrix_f* x 00326 ) 00327 { 00328 uint32_t d, D; 00329 uint32_t n, N; 00330 float sum, ssum; 00331 00332 D = x->num_cols; 00333 N = x->num_rows; 00334 00335 create_vector_f(means_out, D); 00336 create_vector_f(vars_out, D); 00337 create_vector_f(errs_out, D); 00338 00339 for (d = 0; d < D; d++) 00340 { 00341 sum = 0; 00342 ssum = 0; 00343 00344 for (n = 0; n < N; n++) 00345 { 00346 sum += x->elts[ n ][ d ]; 00347 ssum += x->elts[ n ][ d ] * x->elts[ n ][ d ]; 00348 } 00349 00350 (*means_out)->elts[ d ] = sum / (float)N; 00351 00352 if (N > 1) 00353 { 00354 (*vars_out)->elts[ d ] = (1.0 / (float)(N-1)) * 00355 (ssum - ((sum*sum) / (float)N)); 00356 } 00357 else 00358 { 00359 (*vars_out)->elts[ d ] = ssum - sum*sum; 00360 } 00361 00362 (*errs_out)->elts[ d ] = sqrt((*vars_out)->elts[ d ] / (float)N); 00363 } 00364 } 00365 00372 void ind_mv_sample_stats_d 00373 ( 00374 Vector_d** means_out, 00375 Vector_d** vars_out, 00376 Vector_d** errs_out, 00377 const Matrix_d* x 00378 ) 00379 { 00380 uint32_t d, D; 00381 uint32_t n, N; 00382 double sum, ssum; 00383 00384 D = x->num_cols; 00385 N = x->num_rows; 00386 00387 create_vector_d(means_out, D); 00388 create_vector_d(vars_out, D); 00389 create_vector_d(errs_out, D); 00390 00391 for (d = 0; d < D; d++) 00392 { 00393 sum = 0; 00394 ssum = 0; 00395 00396 for (n = 0; n < N; n++) 00397 { 00398 sum += x->elts[ n ][ d ]; 00399 ssum += x->elts[ n ][ d ] * x->elts[ n ][ d ]; 00400 } 00401 00402 (*means_out)->elts[ d ] = sum / (double)N; 00403 00404 if (N > 1) 00405 { 00406 (*vars_out)->elts[ d ] = (1.0 / (double)(N-1)) * 00407 (ssum - ((sum*sum) / (double)N)); 00408 } 00409 else 00410 { 00411 (*vars_out)->elts[ d ] = ssum - sum*sum; 00412 } 00413 00414 (*errs_out)->elts[ d ] = sqrt((*vars_out)->elts[ d ] / (double)N); 00415 } 00416 } 00417 00432 void mv_sample_mean_f(Vector_f** mean_out, const Matrix_f* x) 00433 { 00434 uint32_t n, N; 00435 uint32_t d, D; 00436 Vector_f* mean; 00437 00438 D = x->num_cols; 00439 N = x->num_rows; 00440 00441 create_zero_vector_f(mean_out, D); 00442 mean = *mean_out; 00443 00444 for (n = 0; n < N; n++) 00445 { 00446 for (d = 0; d < D; d++) 00447 { 00448 mean->elts[ d ] += x->elts[ n ][ d ]; 00449 } 00450 } 00451 00452 multiply_vector_by_scalar_f(&mean, mean, 1.0 / (float)N); 00453 } 00454 00459 void mv_sample_mean_d(Vector_d** mean_out, const Matrix_d* x) 00460 { 00461 uint32_t n, N; 00462 uint32_t d, D; 00463 Vector_d* mean; 00464 00465 D = x->num_cols; 00466 N = x->num_rows; 00467 00468 create_zero_vector_d(mean_out, D); 00469 mean = *mean_out; 00470 00471 for (n = 0; n < N; n++) 00472 { 00473 for (d = 0; d < D; d++) 00474 { 00475 mean->elts[ d ] += x->elts[ n ][ d ]; 00476 } 00477 } 00478 00479 multiply_vector_by_scalar_d(&mean, mean, 1.0 / (double)N); 00480 } 00481 00496 void mv_sample_covariance_f(Matrix_f** cov_out, const Matrix_f* x) 00497 { 00498 uint32_t n, N; 00499 uint32_t d, D; 00500 Matrix_f* cov = 0; 00501 Vector_f* mean = 0; 00502 Matrix_f* m = 0; 00503 Matrix_f* m_t = 0; 00504 Matrix_f* M = 0; 00505 00506 mv_sample_mean_f(&mean, x); 00507 00508 D = x->num_cols; 00509 N = x->num_rows; 00510 00511 create_zero_matrix_f(cov_out, D, D); 00512 cov = *cov_out; 00513 00514 create_matrix_f(&m, D, 1); 00515 create_matrix_f(&m_t, 1, D); 00516 create_matrix_f(&M, D, D); 00517 00518 for (n = 0; n < N; n++) 00519 { 00520 for (d = 0; d < D; d++) 00521 { 00522 m->elts[d][0] = m_t->elts[0][d] = x->elts[n][d] - mean->elts[d]; 00523 } 00524 00525 multiply_matrices_f(&M, m, m_t); 00526 add_matrices_f(&cov, cov, M); 00527 } 00528 00529 multiply_matrix_by_scalar_f(&cov, cov, 1.0/(double)(N - 1)); 00530 00531 free_vector_f(mean); 00532 free_matrix_f(m); 00533 free_matrix_f(m_t); 00534 free_matrix_f(M); 00535 } 00536 00541 void mv_sample_covariance_d(Matrix_d** cov_out, const Matrix_d* x) 00542 { 00543 uint32_t n, N; 00544 uint32_t d, D; 00545 Matrix_d* cov = 0; 00546 Vector_d* mean = 0; 00547 Matrix_d* m = 0; 00548 Matrix_d* m_t = 0; 00549 Matrix_d* M = 0; 00550 00551 mv_sample_mean_d(&mean, x); 00552 00553 D = x->num_cols; 00554 N = x->num_rows; 00555 00556 create_zero_matrix_d(cov_out, D, D); 00557 cov = *cov_out; 00558 00559 create_matrix_d(&m, D, 1); 00560 create_matrix_d(&m_t, 1, D); 00561 create_matrix_d(&M, D, D); 00562 00563 for (n = 0; n < N; n++) 00564 { 00565 for (d = 0; d < D; d++) 00566 { 00567 m->elts[d][0] = m_t->elts[0][d] = x->elts[n][d] - mean->elts[d]; 00568 } 00569 00570 multiply_matrices_d(&M, m, m_t); 00571 add_matrices_d(&cov, cov, M); 00572 } 00573 00574 multiply_matrix_by_scalar_d(&cov, cov, 1.0/(double)(N - 1)); 00575 00576 free_vector_d(mean); 00577 free_matrix_d(m); 00578 free_matrix_d(m_t); 00579 free_matrix_d(M); 00580 } 00581 00598 void mv_sample_stats_f 00599 ( 00600 Vector_f** mean_out, 00601 Matrix_f** cov_out, 00602 const Matrix_f* x 00603 ) 00604 { 00605 uint32_t n, N; 00606 uint32_t d, D; 00607 Vector_f* mean; 00608 Matrix_f* cov; 00609 Matrix_f* m = 0; 00610 Matrix_f* m_t = 0; 00611 Matrix_f* M = 0; 00612 00613 D = x->num_cols; 00614 N = x->num_rows; 00615 00616 create_zero_vector_f(mean_out, D); 00617 mean = *mean_out; 00618 00619 for (n = 0; n < N; n++) 00620 { 00621 for (d = 0; d < D; d++) 00622 { 00623 mean->elts[ d ] += x->elts[ n ][ d ]; 00624 } 00625 } 00626 00627 multiply_vector_by_scalar_f(&mean, mean, 1.0 / (float)N); 00628 00629 create_zero_matrix_f(cov_out, D, D); 00630 cov = *cov_out; 00631 00632 create_matrix_f(&m, D, 1); 00633 create_matrix_f(&m_t, 1, D); 00634 create_matrix_f(&M, D, D); 00635 00636 for (n = 0; n < N; n++) 00637 { 00638 for (d = 0; d < D; d++) 00639 { 00640 m->elts[d][0] = m_t->elts[0][d] = x->elts[n][d] - mean->elts[d]; 00641 } 00642 00643 multiply_matrices_f(&M, m, m_t); 00644 add_matrices_f(&cov, cov, M); 00645 } 00646 00647 if (N > 1) 00648 { 00649 multiply_matrix_by_scalar_f(&cov, cov, 1.0/(double)(N - 1)); 00650 } 00651 00652 free_matrix_f(m); 00653 free_matrix_f(m_t); 00654 free_matrix_f(M); 00655 } 00656 00662 void mv_sample_stats_d 00663 ( 00664 Vector_d** mean_out, 00665 Matrix_d** cov_out, 00666 const Matrix_d* x 00667 ) 00668 { 00669 uint32_t n, N; 00670 uint32_t d, D; 00671 Vector_d* mean; 00672 Matrix_d* cov; 00673 Matrix_d* m = 0; 00674 Matrix_d* m_t = 0; 00675 Matrix_d* M = 0; 00676 00677 D = x->num_cols; 00678 N = x->num_rows; 00679 00680 create_zero_vector_d(mean_out, D); 00681 mean = *mean_out; 00682 00683 for (n = 0; n < N; n++) 00684 { 00685 for (d = 0; d < D; d++) 00686 { 00687 mean->elts[ d ] += x->elts[ n ][ d ]; 00688 } 00689 } 00690 00691 multiply_vector_by_scalar_d(&mean, mean, 1.0 / (double)N); 00692 00693 create_zero_matrix_d(cov_out, D, D); 00694 cov = *cov_out; 00695 00696 create_matrix_d(&m, D, 1); 00697 create_matrix_d(&m_t, 1, D); 00698 create_matrix_d(&M, D, D); 00699 00700 for (n = 0; n < N; n++) 00701 { 00702 for (d = 0; d < D; d++) 00703 { 00704 m->elts[d][0] = m_t->elts[0][d] = x->elts[n][d] - mean->elts[d]; 00705 } 00706 00707 multiply_matrices_d(&M, m, m_t); 00708 add_matrices_d(&cov, cov, M); 00709 } 00710 00711 if (N > 1) 00712 { 00713 multiply_matrix_by_scalar_d(&cov, cov, 1.0/(double)(N - 1)); 00714 } 00715 00716 free_matrix_d(m); 00717 free_matrix_d(m_t); 00718 free_matrix_d(M); 00719 } 00720