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 <stdio.h> 00050 #include <assert.h> 00051 #include <math.h> 00052 #include <inttypes.h> 00053 00054 #include "jwsc/base/error.h" 00055 #include "jwsc/math/constants.h" 00056 #include "jwsc/math/lapack.h" 00057 #include "jwsc/vector/vector.h" 00058 #include "jwsc/vector/vector_math.h" 00059 #include "jwsc/matrix/matrix.h" 00060 #include "jwsc/matrix/matrix_math.h" 00061 #include "jwsc/prob/pdf.h" 00062 #include "jwsc/prob/mv_pdf.h" 00063 00064 00065 #if defined JWSC_HAVE_LAPACK 00066 00083 Error* mv_gaussian_pdf_f 00084 ( 00085 float* p_out, 00086 const Vector_f* mu, 00087 const Matrix_f* sigma, 00088 const Vector_f* x 00089 ) 00090 { 00091 uint32_t D; 00092 float sigma_det; 00093 float d; 00094 double c; 00095 Matrix_f* sigma_lu = NULL; 00096 Matrix_f* sigma_inv = NULL; 00097 Vector_i32* pivot = NULL; 00098 Vector_f* v_1 = NULL; 00099 Vector_f* v_2 = NULL; 00100 Error* e; 00101 00102 D = mu->num_elts; 00103 00104 if (D != sigma->num_rows || D != sigma->num_cols || D != x->num_elts) 00105 { 00106 return JWSC_EARG("Invalid argument dimensions"); 00107 } 00108 00109 if ((e = lu_decompose_matrix_f(&sigma_lu, &pivot, sigma)) != NULL) 00110 { 00111 free_error(e); 00112 return JWSC_EARG("Covariance matrix is singular"); 00113 } 00114 00115 calc_lu_matrix_determinant_f(&sigma_det, sigma_lu, pivot); 00116 00117 if (sigma_det < 1.0e-10f) 00118 { 00119 fprintf(stderr, "%e\n", sigma_det); 00120 free_vector_i32(pivot); 00121 free_matrix_f(sigma_lu); 00122 return JWSC_EARG("Invalid covariance matrix"); 00123 } 00124 00125 if ((e = invert_lu_matrix_f(&sigma_inv, sigma_lu, pivot)) != NULL) 00126 { 00127 free_error(e); 00128 free_vector_i32(pivot); 00129 free_matrix_f(sigma_lu); 00130 return JWSC_EARG("Covariance matrix is singular"); 00131 } 00132 00133 c = sqrt(pow(JWSC_2_PI, D) * sigma_det); 00134 00135 subtract_vectors_f(&v_1, x, mu); 00136 multiply_matrix_and_vector_f(&v_2, sigma_inv, v_1); 00137 calc_vector_dot_prod_f(&d, v_1, v_2); 00138 00139 *p_out = (float)(exp(-0.5 * d) / c); 00140 00141 free_vector_i32(pivot); 00142 free_matrix_f(sigma_lu); 00143 free_matrix_f(sigma_inv); 00144 free_vector_f(v_1); 00145 free_vector_f(v_2); 00146 00147 return NULL; 00148 } 00149 00160 Error* mv_gaussian_pdf_d 00161 ( 00162 double* p_out, 00163 const Vector_d* mu, 00164 const Matrix_d* sigma, 00165 const Vector_d* x 00166 ) 00167 { 00168 uint32_t D; 00169 double sigma_det; 00170 double c, d; 00171 Matrix_d* sigma_lu = NULL; 00172 Matrix_d* sigma_inv = NULL; 00173 Vector_i32* pivot = NULL; 00174 Vector_d* v_1 = NULL; 00175 Vector_d* v_2 = NULL; 00176 Error* e; 00177 00178 D = mu->num_elts; 00179 00180 if (D != sigma->num_rows || D != sigma->num_cols || D != x->num_elts) 00181 { 00182 return JWSC_EARG("Invalid argument dimensions"); 00183 } 00184 00185 if ((e = lu_decompose_matrix_d(&sigma_lu, &pivot, sigma)) != NULL) 00186 { 00187 free_error(e); 00188 return JWSC_EARG("Covariance matrix is singular"); 00189 } 00190 00191 calc_lu_matrix_determinant_d(&sigma_det, sigma_lu, pivot); 00192 00193 if (sigma_det < 1.0e-64) 00194 { 00195 fprintf(stderr, "%e\n", sigma_det); 00196 free_vector_i32(pivot); 00197 free_matrix_d(sigma_lu); 00198 return JWSC_EARG("Invalid covariance matrix"); 00199 } 00200 00201 if ((e = invert_lu_matrix_d(&sigma_inv, sigma_lu, pivot)) != NULL) 00202 { 00203 free_error(e); 00204 free_vector_i32(pivot); 00205 free_matrix_d(sigma_lu); 00206 return JWSC_EARG("Covariance matrix is singular"); 00207 } 00208 00209 c = sqrt(pow(JWSC_2_PI, D) * sigma_det); 00210 00211 subtract_vectors_d(&v_1, x, mu); 00212 multiply_matrix_and_vector_d(&v_2, sigma_inv, v_1); 00213 calc_vector_dot_prod_d(&d, v_1, v_2); 00214 00215 *p_out = exp(-0.5 * d) / c; 00216 00217 free_vector_i32(pivot); 00218 free_matrix_d(sigma_lu); 00219 free_matrix_d(sigma_inv); 00220 free_vector_d(v_1); 00221 free_vector_d(v_2); 00222 00223 return NULL; 00224 } 00225 00227 #endif 00228 00229 00230 #if defined JWSC_HAVE_LAPACK 00231 00248 Error* set_mv_gaussian_pdf_f 00249 ( 00250 Vector_f** p_out, 00251 const Vector_f* mu, 00252 const Matrix_f* sigma, 00253 const Matrix_f* x 00254 ) 00255 { 00256 uint32_t D; 00257 uint32_t n, N; 00258 float sigma_det; 00259 double c; 00260 float d; 00261 Matrix_f* sigma_lu = NULL; 00262 Matrix_f* sigma_inv = NULL; 00263 Vector_i32* pivot = NULL; 00264 Vector_f* v_1 = NULL; 00265 Vector_f* v_2 = NULL; 00266 Vector_f* x_n = NULL; 00267 Vector_f* p; 00268 Error* e; 00269 00270 D = x->num_cols; 00271 N = x->num_rows; 00272 00273 if (D != sigma->num_rows || D != sigma->num_cols || D != mu->num_elts) 00274 { 00275 return JWSC_EARG("Invalid argument dimensions"); 00276 } 00277 00278 if ((e = lu_decompose_matrix_f(&sigma_lu, &pivot, sigma)) != NULL) 00279 { 00280 free_error(e); 00281 return JWSC_EARG("Covariance matrix is singular"); 00282 } 00283 00284 calc_lu_matrix_determinant_f(&sigma_det, sigma_lu, pivot); 00285 00286 if (sigma_det < 1.0e-64) 00287 { 00288 fprintf(stderr, "%e\n", sigma_det); 00289 free_vector_i32(pivot); 00290 free_matrix_f(sigma_lu); 00291 return JWSC_EARG("Invalid covariance matrix"); 00292 } 00293 00294 if ((e = invert_lu_matrix_f(&sigma_inv, sigma_lu, pivot)) != NULL) 00295 { 00296 free_error(e); 00297 free_vector_i32(pivot); 00298 free_matrix_f(sigma_lu); 00299 return JWSC_EARG("Covariance matrix is singular"); 00300 } 00301 00302 create_vector_f(p_out, N); 00303 p = *p_out; 00304 00305 c = sqrt(pow(JWSC_2_PI, D) * sigma_det); 00306 00307 for (n = 0; n < N; n++) 00308 { 00309 copy_vector_from_matrix_f(&x_n, x, MATRIX_ROW_VECTOR, n); 00310 subtract_vectors_f(&v_1, x_n, mu); 00311 multiply_matrix_and_vector_f(&v_2, sigma_inv, v_1); 00312 calc_vector_dot_prod_f(&d, v_1, v_2); 00313 00314 p->elts[ n ] = exp(-0.5 * d) / c; 00315 } 00316 00317 free_vector_i32(pivot); 00318 free_matrix_f(sigma_lu); 00319 free_matrix_f(sigma_inv); 00320 free_vector_f(v_1); 00321 free_vector_f(v_2); 00322 free_vector_f(x_n); 00323 00324 return NULL; 00325 } 00326 00337 Error* set_mv_gaussian_pdf_d 00338 ( 00339 Vector_d** p_out, 00340 const Vector_d* mu, 00341 const Matrix_d* sigma, 00342 const Matrix_d* x 00343 ) 00344 { 00345 uint32_t D; 00346 uint32_t n, N; 00347 double sigma_det; 00348 double c, d; 00349 Matrix_d* sigma_lu = NULL; 00350 Matrix_d* sigma_inv = NULL; 00351 Vector_i32* pivot = NULL; 00352 Vector_d* v_1 = NULL; 00353 Vector_d* v_2 = NULL; 00354 Vector_d* x_n = NULL; 00355 Vector_d* p; 00356 Error* e; 00357 00358 D = x->num_cols; 00359 N = x->num_rows; 00360 00361 if (D != sigma->num_rows || D != sigma->num_cols || D != mu->num_elts) 00362 { 00363 return JWSC_EARG("Invalid argument dimensions"); 00364 } 00365 00366 if ((e = lu_decompose_matrix_d(&sigma_lu, &pivot, sigma)) != NULL) 00367 { 00368 free_error(e); 00369 return JWSC_EARG("Covariance matrix is singular"); 00370 } 00371 00372 calc_lu_matrix_determinant_d(&sigma_det, sigma_lu, pivot); 00373 00374 if (sigma_det < 1.0e-64) 00375 { 00376 fprintf(stderr, "%e\n", sigma_det); 00377 free_vector_i32(pivot); 00378 free_matrix_d(sigma_lu); 00379 return JWSC_EARG("Invalid covariance matrix"); 00380 } 00381 00382 if ((e = invert_lu_matrix_d(&sigma_inv, sigma_lu, pivot)) != NULL) 00383 { 00384 free_error(e); 00385 free_vector_i32(pivot); 00386 free_matrix_d(sigma_lu); 00387 return JWSC_EARG("Covariance matrix is singular"); 00388 } 00389 00390 create_vector_d(p_out, N); 00391 p = *p_out; 00392 00393 c = sqrt(pow(JWSC_2_PI, D) * sigma_det); 00394 00395 for (n = 0; n < N; n++) 00396 { 00397 copy_vector_from_matrix_d(&x_n, x, MATRIX_ROW_VECTOR, n); 00398 subtract_vectors_d(&v_1, x_n, mu); 00399 multiply_matrix_and_vector_d(&v_2, sigma_inv, v_1); 00400 calc_vector_dot_prod_d(&d, v_1, v_2); 00401 00402 p->elts[ n ] = exp(-0.5 * d) / c; 00403 } 00404 00405 free_vector_i32(pivot); 00406 free_matrix_d(sigma_lu); 00407 free_matrix_d(sigma_inv); 00408 free_vector_d(v_1); 00409 free_vector_d(v_2); 00410 free_vector_d(x_n); 00411 00412 return NULL; 00413 } 00414 00416 #endif 00417 00418 00419 #if defined JWSC_HAVE_LAPACK 00420 00437 Error* log_mv_gaussian_pdf_f 00438 ( 00439 float* p_out, 00440 const Vector_f* mu, 00441 const Matrix_f* sigma, 00442 const Vector_f* x 00443 ) 00444 { 00445 uint32_t D; 00446 float sigma_det; 00447 float d; 00448 double c; 00449 Matrix_f* sigma_lu = NULL; 00450 Matrix_f* sigma_inv = NULL; 00451 Vector_i32* pivot = NULL; 00452 Vector_f* v_1 = NULL; 00453 Vector_f* v_2 = NULL; 00454 Error* e; 00455 00456 D = mu->num_elts; 00457 00458 if (D != sigma->num_rows || D != sigma->num_cols || D != x->num_elts) 00459 { 00460 return JWSC_EARG("Invalid argument dimensions"); 00461 } 00462 00463 if ((e = lu_decompose_matrix_f(&sigma_lu, &pivot, sigma)) != NULL) 00464 { 00465 free_error(e); 00466 return JWSC_EARG("Covariance matrix is singular"); 00467 } 00468 00469 calc_lu_matrix_determinant_f(&sigma_det, sigma_lu, pivot); 00470 00471 if (sigma_det < 1.0e-10f) 00472 { 00473 fprintf(stderr, "%e\n", sigma_det); 00474 free_vector_i32(pivot); 00475 free_matrix_f(sigma_lu); 00476 return JWSC_EARG("Invalid covariance matrix"); 00477 } 00478 00479 if ((e = invert_lu_matrix_f(&sigma_inv, sigma_lu, pivot)) != NULL) 00480 { 00481 free_error(e); 00482 free_vector_i32(pivot); 00483 free_matrix_f(sigma_lu); 00484 return JWSC_EARG("Covariance matrix is singular"); 00485 } 00486 00487 c = sqrt(pow(JWSC_2_PI, D) * sigma_det); 00488 00489 subtract_vectors_f(&v_1, x, mu); 00490 multiply_matrix_and_vector_f(&v_2, sigma_inv, v_1); 00491 calc_vector_dot_prod_f(&d, v_1, v_2); 00492 00493 *p_out = (float)(-0.5 * d - log(c)); 00494 00495 free_vector_i32(pivot); 00496 free_matrix_f(sigma_lu); 00497 free_matrix_f(sigma_inv); 00498 free_vector_f(v_1); 00499 free_vector_f(v_2); 00500 00501 return NULL; 00502 } 00503 00514 Error* log_mv_gaussian_pdf_d 00515 ( 00516 double* p_out, 00517 const Vector_d* mu, 00518 const Matrix_d* sigma, 00519 const Vector_d* x 00520 ) 00521 { 00522 uint32_t D; 00523 double sigma_det; 00524 double c, d; 00525 Matrix_d* sigma_lu = NULL; 00526 Matrix_d* sigma_inv = NULL; 00527 Vector_i32* pivot = NULL; 00528 Vector_d* v_1 = NULL; 00529 Vector_d* v_2 = NULL; 00530 Error* e; 00531 00532 D = mu->num_elts; 00533 00534 if (D != sigma->num_rows || D != sigma->num_cols || D != x->num_elts) 00535 { 00536 return JWSC_EARG("Invalid argument dimensions"); 00537 } 00538 00539 if ((e = lu_decompose_matrix_d(&sigma_lu, &pivot, sigma)) != NULL) 00540 { 00541 free_error(e); 00542 return JWSC_EARG("Covariance matrix is singular"); 00543 } 00544 00545 calc_lu_matrix_determinant_d(&sigma_det, sigma_lu, pivot); 00546 00547 if (sigma_det < 1.0e-64) 00548 { 00549 fprintf(stderr, "%e\n", sigma_det); 00550 free_vector_i32(pivot); 00551 free_matrix_d(sigma_lu); 00552 return JWSC_EARG("Invalid covariance matrix"); 00553 } 00554 00555 if ((e = invert_lu_matrix_d(&sigma_inv, sigma_lu, pivot)) != NULL) 00556 { 00557 free_error(e); 00558 free_vector_i32(pivot); 00559 free_matrix_d(sigma_lu); 00560 return JWSC_EARG("Covariance matrix is singular"); 00561 } 00562 00563 c = sqrt(pow(JWSC_2_PI, D) * sigma_det); 00564 00565 subtract_vectors_d(&v_1, x, mu); 00566 multiply_matrix_and_vector_d(&v_2, sigma_inv, v_1); 00567 calc_vector_dot_prod_d(&d, v_1, v_2); 00568 00569 *p_out = -0.5 * d - log(c); 00570 00571 free_vector_i32(pivot); 00572 free_matrix_d(sigma_lu); 00573 free_matrix_d(sigma_inv); 00574 free_vector_d(v_1); 00575 free_vector_d(v_2); 00576 00577 return NULL; 00578 } 00579 00581 #endif 00582 00583 00601 void sample_standard_mv_gaussian_pdf_f 00602 ( 00603 Vector_f** x_out, 00604 uint32_t D 00605 ) 00606 { 00607 uint32_t d; 00608 uint8_t accept; 00609 float s, l, u; 00610 Vector_f* x; 00611 00612 create_vector_f(x_out, D); 00613 x = *x_out; 00614 00615 for (d = 0; d < D; d++) 00616 { 00617 accept = 0; 00618 00619 while (!accept) 00620 { 00621 s = sample_uniform_pdf_f(-6.0, 6.0); 00622 l = standard_gaussian_pdf_f(s); 00623 u = sample_uniform_pdf_f(0, 1); 00624 00625 if (u <= l) 00626 { 00627 accept = 1; 00628 } 00629 } 00630 00631 x->elts[ d ] = s; 00632 } 00633 } 00634 00645 void sample_standard_mv_gaussian_pdf_d 00646 ( 00647 Vector_d** x_out, 00648 uint32_t D 00649 ) 00650 { 00651 uint32_t d; 00652 uint8_t accept; 00653 double s, l, u; 00654 Vector_d* x; 00655 00656 create_vector_d(x_out, D); 00657 x = *x_out; 00658 00659 for (d = 0; d < D; d++) 00660 { 00661 accept = 0; 00662 00663 while (!accept) 00664 { 00665 s = sample_uniform_pdf_d(-6.0, 6.0); 00666 l = standard_gaussian_pdf_d(s); 00667 u = sample_uniform_pdf_d(0, 1); 00668 00669 if (u <= l) 00670 { 00671 accept = 1; 00672 } 00673 } 00674 00675 x->elts[ d ] = s; 00676 } 00677 } 00678 00700 void set_sample_standard_mv_gaussian_pdf_f 00701 ( 00702 Matrix_f** x_out, 00703 uint32_t N, 00704 uint32_t D 00705 ) 00706 { 00707 uint32_t n, d; 00708 uint8_t accept; 00709 float s, l, u; 00710 Matrix_f* x; 00711 00712 create_matrix_f(x_out, N, D); 00713 x = *x_out; 00714 00715 for (n = 0; n < N; n++) 00716 { 00717 for (d = 0; d < D; d++) 00718 { 00719 accept = 0; 00720 00721 while (!accept) 00722 { 00723 s = sample_uniform_pdf_f(-6.0f, 6.0f); 00724 l = standard_gaussian_pdf_f(s); 00725 u = sample_uniform_pdf_f(0, 1); 00726 00727 if (u <= l) 00728 { 00729 accept = 1; 00730 } 00731 } 00732 00733 x->elts[ n ][ d ] = s; 00734 } 00735 } 00736 } 00737 00749 void set_sample_standard_mv_gaussian_pdf_d 00750 ( 00751 Matrix_d** x_out, 00752 uint32_t N, 00753 uint32_t D 00754 ) 00755 { 00756 uint32_t n, d; 00757 uint8_t accept; 00758 double s, l, u; 00759 Matrix_d* x; 00760 00761 create_matrix_d(x_out, N, D); 00762 x = *x_out; 00763 00764 for (n = 0; n < N; n++) 00765 { 00766 for (d = 0; d < D; d++) 00767 { 00768 accept = 0; 00769 00770 while (!accept) 00771 { 00772 s = sample_uniform_pdf_d(-6.0, 6.0); 00773 l = standard_gaussian_pdf_d(s); 00774 u = sample_uniform_pdf_d(0, 1); 00775 00776 if (u <= l) 00777 { 00778 accept = 1; 00779 } 00780 } 00781 00782 x->elts[ n ][ d ] = s; 00783 } 00784 } 00785 } 00786 00790 #if defined JWSC_HAVE_LAPACK 00791 00809 Error* sample_mv_gaussian_pdf_f 00810 ( 00811 Vector_f** x_out, 00812 const Vector_f* mu, 00813 const Matrix_f* sigma 00814 ) 00815 { 00816 uint32_t D, d; 00817 Vector_f* x; 00818 Matrix_f* eigvec = NULL; 00819 Vector_f* eigval = NULL; 00820 Error* err; 00821 00822 D = mu->num_elts; 00823 00824 sample_standard_mv_gaussian_pdf_f(x_out, D); 00825 x = *x_out; 00826 00827 if ((err = solve_real_symmetric_matrix_eigenproblem_f(&eigvec, &eigval, 00828 sigma))) 00829 { 00830 free_vector_f(*x_out); *x_out = NULL; 00831 return err; 00832 } 00833 00834 for (d = 0; d < D; d++) 00835 { 00836 if (eigval->elts[ d ] < 0) 00837 { 00838 free_vector_f(*x_out); *x_out = NULL; 00839 free_matrix_f(eigvec); 00840 free_vector_f(eigval); 00841 return JWSC_EARG("Covariance matrix not positive semi-definite"); 00842 } 00843 00844 x->elts[ d ] *= sqrt(eigval->elts[ d ]); 00845 } 00846 00847 assert(multiply_matrix_and_vector_f(&x, eigvec, x) == NULL); 00848 assert(add_vectors_f(&x, mu, x) == NULL); 00849 00850 free_matrix_f(eigvec); 00851 free_vector_f(eigval); 00852 00853 return NULL; 00854 } 00855 00867 Error* sample_mv_gaussian_pdf_d 00868 ( 00869 Vector_d** x_out, 00870 const Vector_d* mu, 00871 const Matrix_d* sigma 00872 ) 00873 { 00874 uint32_t D, d; 00875 Vector_d* x; 00876 Matrix_d* eigvec = NULL; 00877 Vector_d* eigval = NULL; 00878 Error* err; 00879 00880 D = mu->num_elts; 00881 00882 sample_standard_mv_gaussian_pdf_d(x_out, D); 00883 x = *x_out; 00884 00885 if ((err = solve_real_symmetric_matrix_eigenproblem_d(&eigvec, &eigval, 00886 sigma))) 00887 { 00888 free_vector_d(*x_out); *x_out = NULL; 00889 return err; 00890 } 00891 00892 for (d = 0; d < D; d++) 00893 { 00894 if (eigval->elts[ d ] < -1.0e-16) 00895 { 00896 free_vector_d(*x_out); *x_out = NULL; 00897 free_matrix_d(eigvec); 00898 free_vector_d(eigval); 00899 return JWSC_EARG("Covariance matrix not positive semi-definite"); 00900 } 00901 else if (eigval->elts[ d ] < 0) 00902 { 00903 eigval->elts[ d ] = 0; 00904 } 00905 else 00906 { 00907 x->elts[ d ] *= sqrt(eigval->elts[ d ]); 00908 } 00909 } 00910 00911 assert(multiply_matrix_and_vector_d(&x, eigvec, x) == NULL); 00912 assert(add_vectors_d(&x, mu, x) == NULL); 00913 00914 free_matrix_d(eigvec); 00915 free_vector_d(eigval); 00916 00917 return NULL; 00918 } 00919 00921 #endif 00922 00923 00924 #if defined JWSC_HAVE_LAPACK 00925 00944 Error* set_sample_mv_gaussian_pdf_f 00945 ( 00946 Matrix_f** x_out, 00947 uint32_t N, 00948 const Vector_f* mu, 00949 const Matrix_f* sigma 00950 ) 00951 { 00952 uint32_t D, d; 00953 uint32_t n; 00954 Matrix_f* x; 00955 Matrix_f* eigvec = NULL; 00956 Vector_f* eigval = NULL; 00957 Error* err; 00958 00959 D = mu->num_elts; 00960 00961 set_sample_standard_mv_gaussian_pdf_f(x_out, N, D); 00962 x = *x_out; 00963 00964 if ((err = solve_real_symmetric_matrix_eigenproblem_f(&eigvec, &eigval, 00965 sigma))) 00966 { 00967 free_matrix_f(*x_out); *x_out = NULL; 00968 return err; 00969 } 00970 00971 for (d = 0; d < D; d++) 00972 { 00973 if (eigval->elts[ d ] < 0) 00974 { 00975 free_matrix_f(*x_out); *x_out = NULL; 00976 free_matrix_f(eigvec); 00977 free_vector_f(eigval); 00978 return JWSC_EARG("Covariance matrix not positive semi-definite"); 00979 } 00980 } 00981 00982 for (n = 0; n < N; n++) 00983 { 00984 for (d = 0; d < D; d++) 00985 { 00986 x->elts[ n ][ d ] *= sqrt(eigval->elts[ d ]); 00987 } 00988 } 00989 00990 transpose_matrix_f(&eigvec, eigvec); 00991 assert(multiply_matrices_f(&x, x, eigvec) == NULL); 00992 00993 for (n = 0; n < N; n++) 00994 { 00995 for (d = 0; d < D; d++) 00996 { 00997 x->elts[ n ][ d ] += mu->elts[ d ]; 00998 } 00999 } 01000 01001 free_matrix_f(eigvec); 01002 free_vector_f(eigval); 01003 01004 return NULL; 01005 } 01006 01019 Error* set_sample_mv_gaussian_pdf_d 01020 ( 01021 Matrix_d** x_out, 01022 uint32_t N, 01023 const Vector_d* mu, 01024 const Matrix_d* sigma 01025 ) 01026 { 01027 uint32_t D, d; 01028 uint32_t n; 01029 Matrix_d* x; 01030 Matrix_d* eigvec = NULL; 01031 Vector_d* eigval = NULL; 01032 Error* err; 01033 01034 D = mu->num_elts; 01035 01036 set_sample_standard_mv_gaussian_pdf_d(x_out, N, D); 01037 x = *x_out; 01038 01039 if ((err = solve_real_symmetric_matrix_eigenproblem_d(&eigvec, &eigval, 01040 sigma))) 01041 { 01042 free_matrix_d(*x_out); *x_out = NULL; 01043 return err; 01044 } 01045 01046 for (d = 0; d < D; d++) 01047 { 01048 if (eigval->elts[ d ] < 0) 01049 { 01050 free_matrix_d(*x_out); *x_out = NULL; 01051 free_matrix_d(eigvec); 01052 free_vector_d(eigval); 01053 return JWSC_EARG("Covariance matrix not positive semi-definite"); 01054 } 01055 } 01056 01057 for (n = 0; n < N; n++) 01058 { 01059 for (d = 0; d < D; d++) 01060 { 01061 x->elts[ n ][ d ] *= sqrt(eigval->elts[ d ]); 01062 } 01063 } 01064 01065 transpose_matrix_d(&eigvec, eigvec); 01066 assert(multiply_matrices_d(&x, x, eigvec) == NULL); 01067 01068 for (n = 0; n < N; n++) 01069 { 01070 for (d = 0; d < D; d++) 01071 { 01072 x->elts[ n ][ d ] += mu->elts[ d ]; 01073 } 01074 } 01075 01076 free_matrix_d(eigvec); 01077 free_vector_d(eigval); 01078 01079 return NULL; 01080 } 01081 01083 #endif