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 00049 #include <jwsc/config.h> 00050 00051 #include <stdlib.h> 00052 #include <assert.h> 00053 #include <math.h> 00054 #include <inttypes.h> 00055 00056 #include "jwsc/base/error.h" 00057 #include "jwsc/math/complex.h" 00058 #include "jwsc/math/blas.h" 00059 #include "jwsc/matblock/matblock.h" 00060 #include "jwsc/matblock/matblock_math.h" 00061 00062 00078 void add_scalar_to_matblock_f 00079 ( 00080 Matblock_f** m_out, 00081 const Matblock_f* m_in, 00082 float a 00083 ) 00084 { 00085 uint32_t num_elts; 00086 uint32_t elt; 00087 float* m_in_elts; 00088 float* m_out_elts; 00089 00090 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00091 00092 if (*m_out != m_in) 00093 { 00094 create_matblock_f(m_out, m_in->num_mats, m_in->num_rows, 00095 m_in->num_cols); 00096 } 00097 m_out_elts = **((*m_out)->elts); 00098 m_in_elts = **(m_in->elts); 00099 00100 for (elt = 0; elt < num_elts; elt++) 00101 { 00102 m_out_elts[ elt ] = a + m_in_elts[ elt ]; 00103 } 00104 } 00105 00114 void add_scalar_to_matblock_d 00115 ( 00116 Matblock_d** m_out, 00117 const Matblock_d* m_in, 00118 double a 00119 ) 00120 { 00121 uint32_t num_elts; 00122 uint32_t elt; 00123 double* m_in_elts; 00124 double* m_out_elts; 00125 00126 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00127 00128 if (*m_out != m_in) 00129 { 00130 create_matblock_d(m_out, m_in->num_mats, m_in->num_rows, 00131 m_in->num_cols); 00132 } 00133 m_out_elts = **((*m_out)->elts); 00134 m_in_elts = **(m_in->elts); 00135 00136 for (elt = 0; elt < num_elts; elt++) 00137 { 00138 m_out_elts[ elt ] = a + m_in_elts[ elt ]; 00139 } 00140 } 00141 00150 void add_scalar_to_matblock_cf 00151 ( 00152 Matblock_cf** m_out, 00153 const Matblock_cf* m_in, 00154 Complex_f z 00155 ) 00156 { 00157 uint32_t num_elts; 00158 uint32_t elt; 00159 Complex_f* m_in_elts; 00160 Complex_f* m_out_elts; 00161 00162 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00163 00164 if (*m_out != m_in) 00165 { 00166 create_matblock_cf(m_out, m_in->num_mats, m_in->num_rows, 00167 m_in->num_cols); 00168 } 00169 m_out_elts = **((*m_out)->elts); 00170 m_in_elts = **(m_in->elts); 00171 00172 for (elt = 0; elt < num_elts; elt++) 00173 { 00174 m_out_elts[ elt ].r = z.r + m_in_elts[ elt ].r; 00175 m_out_elts[ elt ].i = z.i + m_in_elts[ elt ].i; 00176 } 00177 } 00178 00187 void add_scalar_to_matblock_cd 00188 ( 00189 Matblock_cd** m_out, 00190 const Matblock_cd* m_in, 00191 Complex_d z 00192 ) 00193 { 00194 uint32_t num_elts; 00195 uint32_t elt; 00196 Complex_d* m_in_elts; 00197 Complex_d* m_out_elts; 00198 00199 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00200 00201 if (*m_out != m_in) 00202 { 00203 create_matblock_cd(m_out, m_in->num_mats, m_in->num_rows, 00204 m_in->num_cols); 00205 } 00206 m_out_elts = **((*m_out)->elts); 00207 m_in_elts = **(m_in->elts); 00208 00209 for (elt = 0; elt < num_elts; elt++) 00210 { 00211 m_out_elts[ elt ].r = z.r + m_in_elts[ elt ].r; 00212 m_out_elts[ elt ].i = z.i + m_in_elts[ elt ].i; 00213 } 00214 } 00215 00236 void multiply_matblock_by_scalar_f 00237 ( 00238 Matblock_f** m_out, 00239 const Matblock_f* m_in, 00240 float a 00241 ) 00242 { 00243 uint32_t num_elts; 00244 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00245 #else 00246 uint32_t elt; 00247 float* m_out_elts; 00248 float* m_in_elts; 00249 #endif 00250 00251 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00252 00253 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00254 if (*m_out != m_in) 00255 { 00256 copy_matblock_f(m_out, m_in); 00257 } 00258 00259 blas_sscal(num_elts, a, **((*m_out)->elts), 1); 00260 #else 00261 if (*m_out != m_in) 00262 { 00263 create_matblock_f(m_out, m_in->num_mats, m_in->num_rows, 00264 m_in->num_cols); 00265 } 00266 00267 m_out_elts = **((*m_out)->elts); 00268 m_in_elts = **(m_in->elts); 00269 00270 for (elt = 0; elt < num_elts; elt++) 00271 { 00272 m_out_elts[ elt ] = a * m_in_elts[ elt ]; 00273 } 00274 #endif 00275 } 00276 00285 void multiply_matblock_by_scalar_d 00286 ( 00287 Matblock_d** m_out, 00288 const Matblock_d* m_in, 00289 double a 00290 ) 00291 { 00292 uint32_t num_elts; 00293 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00294 #else 00295 uint32_t elt; 00296 double* m_out_elts; 00297 double* m_in_elts; 00298 #endif 00299 00300 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00301 00302 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00303 if (*m_out != m_in) 00304 { 00305 copy_matblock_d(m_out, m_in); 00306 } 00307 00308 blas_dscal(num_elts, a, **((*m_out)->elts), 1); 00309 #else 00310 if (*m_out != m_in) 00311 { 00312 create_matblock_d(m_out, m_in->num_mats, m_in->num_rows, 00313 m_in->num_cols); 00314 } 00315 00316 m_out_elts = **((*m_out)->elts); 00317 m_in_elts = **(m_in->elts); 00318 00319 for (elt = 0; elt < num_elts; elt++) 00320 { 00321 m_out_elts[ elt ] = a * m_in_elts[ elt ]; 00322 } 00323 #endif 00324 } 00325 00334 void multiply_matblock_by_scalar_cf 00335 ( 00336 Matblock_cf** m_out, 00337 const Matblock_cf* m_in, 00338 Complex_f z 00339 ) 00340 { 00341 uint32_t num_elts; 00342 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00343 #else 00344 uint32_t elt; 00345 float r, i; 00346 Complex_f* m_out_elts; 00347 Complex_f* m_in_elts; 00348 #endif 00349 00350 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00351 00352 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00353 if (*m_out != m_in) 00354 { 00355 copy_matblock_cf(m_out, m_in); 00356 } 00357 00358 blas_cscal(num_elts, z, **((*m_out)->elts), 1); 00359 #else 00360 if (*m_out != m_in) 00361 { 00362 create_matblock_cf(m_out, m_in->num_mats, m_in->num_rows, 00363 m_in->num_cols); 00364 } 00365 00366 m_out_elts = **((*m_out)->elts); 00367 m_in_elts = **(m_in->elts); 00368 00369 for (elt = 0; elt < num_elts; elt++) 00370 { 00371 r = z.r*m_in_elts[ elt ].r - z.i*m_in_elts[ elt ].i; 00372 i = z.i*m_in_elts[ elt ].r + z.r*m_in_elts[ elt ].i; 00373 00374 m_out_elts[ elt ].r = r; 00375 m_out_elts[ elt ].i = i; 00376 } 00377 #endif 00378 } 00379 00388 void multiply_matblock_by_scalar_cd 00389 ( 00390 Matblock_cd** m_out, 00391 const Matblock_cd* m_in, 00392 Complex_d z 00393 ) 00394 { 00395 uint32_t num_elts; 00396 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00397 #else 00398 uint32_t elt; 00399 double r, i; 00400 Complex_d* m_out_elts; 00401 Complex_d* m_in_elts; 00402 #endif 00403 00404 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 00405 00406 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00407 if (*m_out != m_in) 00408 { 00409 copy_matblock_cd(m_out, m_in); 00410 } 00411 00412 blas_zscal(num_elts, z, **((*m_out)->elts), 1); 00413 #else 00414 if (*m_out != m_in) 00415 { 00416 create_matblock_cd(m_out, m_in->num_mats, m_in->num_rows, 00417 m_in->num_cols); 00418 } 00419 00420 m_out_elts = **((*m_out)->elts); 00421 m_in_elts = **(m_in->elts); 00422 00423 for (elt = 0; elt < num_elts; elt++) 00424 { 00425 r = z.r*m_in_elts[ elt ].r - z.i*m_in_elts[ elt ].i; 00426 i = z.i*m_in_elts[ elt ].r + z.r*m_in_elts[ elt ].i; 00427 00428 m_out_elts[ elt ].r = r; 00429 m_out_elts[ elt ].i = i; 00430 } 00431 #endif 00432 } 00433 00461 Error* multiply_matblocks_elt_wise_f 00462 ( 00463 Matblock_f** m_out, 00464 const Matblock_f* m_1, 00465 const Matblock_f* m_2 00466 ) 00467 { 00468 uint32_t num_mats, num_rows, num_cols; 00469 uint32_t num_elts; 00470 uint32_t elt; 00471 float* m_out_elts; 00472 float* m_1_elts; 00473 float* m_2_elts; 00474 00475 num_mats = m_1->num_mats; 00476 num_rows = m_1->num_rows; 00477 num_cols = m_1->num_cols; 00478 00479 if (num_mats != m_2->num_mats || 00480 num_rows != m_2->num_rows || 00481 num_cols != m_2->num_cols) 00482 { 00483 if (*m_out != m_1 && *m_out != m_2) 00484 { 00485 free_matblock_f(*m_out); *m_out = NULL; 00486 } 00487 return JWSC_EARG("Matblocks do not have the same dimensions"); 00488 } 00489 00490 m_out_elts = **((*m_out)->elts); 00491 m_1_elts = **(m_1->elts); 00492 m_2_elts = **(m_2->elts); 00493 00494 num_elts = num_mats*num_rows*num_cols; 00495 for (elt = 0; elt < num_elts; elt++) 00496 { 00497 m_out_elts[ elt ] = m_1_elts[ elt ]*m_2_elts[ elt ]; 00498 } 00499 00500 return NULL; 00501 } 00502 00503 Error* multiply_matblocks_elt_wise_d 00504 ( 00505 Matblock_d** m_out, 00506 const Matblock_d* m_1, 00507 const Matblock_d* m_2 00508 ) 00509 { 00510 uint32_t num_mats, num_rows, num_cols; 00511 uint32_t num_elts; 00512 uint32_t elt; 00513 double* m_out_elts; 00514 double* m_1_elts; 00515 double* m_2_elts; 00516 00517 num_mats = m_1->num_mats; 00518 num_rows = m_1->num_rows; 00519 num_cols = m_1->num_cols; 00520 00521 if (num_mats != m_2->num_mats || 00522 num_rows != m_2->num_rows || 00523 num_cols != m_2->num_cols) 00524 { 00525 if (*m_out != m_1 && *m_out != m_2) 00526 { 00527 free_matblock_d(*m_out); *m_out = NULL; 00528 } 00529 return JWSC_EARG("Matblocks do not have the same dimensions"); 00530 } 00531 00532 m_out_elts = **((*m_out)->elts); 00533 m_1_elts = **(m_1->elts); 00534 m_2_elts = **(m_2->elts); 00535 00536 num_elts = num_mats*num_rows*num_cols; 00537 for (elt = 0; elt < num_elts; elt++) 00538 { 00539 m_out_elts[ elt ] = m_1_elts[ elt ]*m_2_elts[ elt ]; 00540 } 00541 00542 return NULL; 00543 } 00544 00545 Error* multiply_matblocks_elt_wise_cf 00546 ( 00547 Matblock_cf** m_out, 00548 const Matblock_cf* m_1, 00549 const Matblock_cf* m_2 00550 ) 00551 { 00552 uint32_t num_mats, num_rows, num_cols; 00553 uint32_t num_elts; 00554 uint32_t elt; 00555 float r, i; 00556 Complex_f* m_out_elts; 00557 Complex_f* m_1_elts; 00558 Complex_f* m_2_elts; 00559 00560 num_mats = m_1->num_mats; 00561 num_rows = m_1->num_rows; 00562 num_cols = m_1->num_cols; 00563 00564 if (num_mats != m_2->num_mats || 00565 num_rows != m_2->num_rows || 00566 num_cols != m_2->num_cols) 00567 { 00568 if (*m_out != m_1 && *m_out != m_2) 00569 { 00570 free_matblock_cf(*m_out); *m_out = NULL; 00571 } 00572 return JWSC_EARG("Matblocks do not have the same dimensions"); 00573 } 00574 00575 m_out_elts = **((*m_out)->elts); 00576 m_1_elts = **(m_1->elts); 00577 m_2_elts = **(m_2->elts); 00578 00579 num_elts = num_mats*num_rows*num_cols; 00580 for (elt = 0; elt < num_elts; elt++) 00581 { 00582 r = m_1_elts[ elt ].r * m_2_elts[ elt ].r - 00583 m_1_elts[ elt ].i * m_2_elts[ elt ].i; 00584 i = m_1_elts[ elt ].i * m_2_elts[ elt ].r + 00585 m_1_elts[ elt ].r * m_2_elts[ elt ].i; 00586 00587 m_out_elts[ elt ].r = r; 00588 m_out_elts[ elt ].i = i; 00589 } 00590 00591 return NULL; 00592 } 00593 00594 Error* multiply_matblocks_elt_wise_cd 00595 ( 00596 Matblock_cd** m_out, 00597 const Matblock_cd* m_1, 00598 const Matblock_cd* m_2 00599 ) 00600 { 00601 uint32_t num_mats, num_rows, num_cols; 00602 uint32_t num_elts; 00603 uint32_t elt; 00604 double r, i; 00605 Complex_d* m_out_elts; 00606 Complex_d* m_1_elts; 00607 Complex_d* m_2_elts; 00608 00609 num_mats = m_1->num_mats; 00610 num_rows = m_1->num_rows; 00611 num_cols = m_1->num_cols; 00612 00613 if (num_mats != m_2->num_mats || 00614 num_rows != m_2->num_rows || 00615 num_cols != m_2->num_cols) 00616 { 00617 if (*m_out != m_1 && *m_out != m_2) 00618 { 00619 free_matblock_cd(*m_out); *m_out = NULL; 00620 } 00621 return JWSC_EARG("Matblocks do not have the same dimensions"); 00622 } 00623 00624 m_out_elts = **((*m_out)->elts); 00625 m_1_elts = **(m_1->elts); 00626 m_2_elts = **(m_2->elts); 00627 00628 num_elts = num_mats*num_rows*num_cols; 00629 for (elt = 0; elt < num_elts; elt++) 00630 { 00631 r = m_1_elts[ elt ].r * m_2_elts[ elt ].r - 00632 m_1_elts[ elt ].i * m_2_elts[ elt ].i; 00633 i = m_1_elts[ elt ].i * m_2_elts[ elt ].r + 00634 m_1_elts[ elt ].r * m_2_elts[ elt ].i; 00635 00636 m_out_elts[ elt ].r = r; 00637 m_out_elts[ elt ].i = i; 00638 } 00639 00640 return NULL; 00641 } 00642 00670 Error* add_matblocks_f 00671 ( 00672 Matblock_f** m_out, 00673 const Matblock_f* m_1, 00674 const Matblock_f* m_2 00675 ) 00676 { 00677 uint32_t num_elts; 00678 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00679 #else 00680 uint32_t elt; 00681 float* m_1_elts; 00682 float* m_2_elts; 00683 float* m_out_elts; 00684 #endif 00685 00686 if (m_1->num_mats != m_2->num_mats || 00687 m_1->num_rows != m_2->num_rows || 00688 m_1->num_cols != m_2->num_cols) 00689 { 00690 if (*m_out != m_1 && *m_out != m_2) 00691 { 00692 free_matblock_f(*m_out); *m_out = NULL; 00693 } 00694 return JWSC_EARG("Adding matblocks requires equal dimensions"); 00695 } 00696 00697 num_elts = m_1->num_mats*m_1->num_rows*m_1->num_cols; 00698 00699 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00700 if (*m_out == m_1) 00701 { 00702 blas_saxpy(num_elts, 1, **(m_2->elts), 1, **(m_1->elts), 1); 00703 } 00704 else if (*m_out == m_2) 00705 { 00706 blas_saxpy(num_elts, 1, **(m_1->elts), 1, **(m_2->elts), 1); 00707 } 00708 else 00709 { 00710 copy_matblock_f(m_out, m_2); 00711 blas_saxpy(num_elts, 1, **(m_1->elts), 1, **((*m_out)->elts), 1); 00712 } 00713 #else 00714 m_1_elts = **(m_1->elts); 00715 m_2_elts = **(m_2->elts); 00716 m_out_elts = **((*m_out)->elts); 00717 00718 if (*m_out == m_1) 00719 { 00720 for (elt = 0; elt < num_elts; elt++) 00721 { 00722 m_1_elts[ elt ] += m_2_elts[ elt ]; 00723 } 00724 } 00725 else if (*m_out == m_2) 00726 { 00727 for (elt = 0; elt < num_elts; elt++) 00728 { 00729 m_2_elts[ elt ] += m_1_elts[ elt ]; 00730 } 00731 } 00732 else 00733 { 00734 create_matblock_f(m_out, m_1->num_cols, m_1->num_rows, m_1->num_cols); 00735 for (elt = 0; elt < num_elts; elt++) 00736 { 00737 m_out_elts[ elt ] = m_1_elts[ elt ] + m_2_elts[ elt ]; 00738 } 00739 } 00740 #endif 00741 00742 return NULL; 00743 } 00744 00760 Error* add_matblocks_d 00761 ( 00762 Matblock_d** m_out, 00763 const Matblock_d* m_1, 00764 const Matblock_d* m_2 00765 ) 00766 { 00767 uint32_t num_elts; 00768 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00769 #else 00770 uint32_t elt; 00771 double* m_1_elts; 00772 double* m_2_elts; 00773 double* m_out_elts; 00774 #endif 00775 00776 if (m_1->num_mats != m_2->num_mats || 00777 m_1->num_rows != m_2->num_rows || 00778 m_1->num_cols != m_2->num_cols) 00779 { 00780 if (*m_out != m_1 && *m_out != m_2) 00781 { 00782 free_matblock_d(*m_out); *m_out = NULL; 00783 } 00784 return JWSC_EARG("Adding matblocks requires equal dimensions"); 00785 } 00786 00787 num_elts = m_1->num_mats*m_1->num_rows*m_1->num_cols; 00788 00789 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00790 if (*m_out == m_1) 00791 { 00792 blas_daxpy(num_elts, 1, **(m_2->elts), 1, **(m_1->elts), 1); 00793 } 00794 else if (*m_out == m_2) 00795 { 00796 blas_daxpy(num_elts, 1, **(m_1->elts), 1, **(m_2->elts), 1); 00797 } 00798 else 00799 { 00800 copy_matblock_d(m_out, m_2); 00801 blas_daxpy(num_elts, 1, **(m_1->elts), 1, **((*m_out)->elts), 1); 00802 } 00803 #else 00804 m_1_elts = **(m_1->elts); 00805 m_2_elts = **(m_2->elts); 00806 m_out_elts = **((*m_out)->elts); 00807 00808 if (*m_out == m_1) 00809 { 00810 for (elt = 0; elt < num_elts; elt++) 00811 { 00812 m_1_elts[ elt ] += m_2_elts[ elt ]; 00813 } 00814 } 00815 else if (*m_out == m_2) 00816 { 00817 for (elt = 0; elt < num_elts; elt++) 00818 { 00819 m_2_elts[ elt ] += m_1_elts[ elt ]; 00820 } 00821 } 00822 else 00823 { 00824 create_matblock_d(m_out, m_1->num_cols, m_1->num_rows, m_1->num_cols); 00825 for (elt = 0; elt < num_elts; elt++) 00826 { 00827 m_out_elts[ elt ] = m_1_elts[ elt ] + m_2_elts[ elt ]; 00828 } 00829 } 00830 #endif 00831 00832 return NULL; 00833 } 00834 00862 Error* subtract_matblocks_f 00863 ( 00864 Matblock_f** m_out, 00865 const Matblock_f* m_1, 00866 const Matblock_f* m_2 00867 ) 00868 { 00869 uint32_t num_elts; 00870 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00871 Matblock_f* m = NULL; 00872 #else 00873 uint32_t elt; 00874 float* m_1_elts; 00875 float* m_2_elts; 00876 float* m_out_elts; 00877 #endif 00878 00879 if (m_1->num_mats != m_2->num_mats || 00880 m_1->num_rows != m_2->num_rows || 00881 m_1->num_cols != m_2->num_cols) 00882 { 00883 if (*m_out != m_1 && *m_out != m_2) 00884 { 00885 free_matblock_f(*m_out); *m_out = NULL; 00886 } 00887 return JWSC_EARG("Subtracting matblocks requires equal dimensions"); 00888 } 00889 00890 num_elts = m_1->num_mats*m_1->num_rows*m_1->num_cols; 00891 00892 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00893 if (*m_out == m_1) 00894 { 00895 blas_saxpy(num_elts, -1, **(m_2->elts), 1, **(m_1->elts), 1); 00896 } 00897 else if (*m_out == m_2) 00898 { 00899 copy_matblock_f(&m, m_1); 00900 blas_saxpy(num_elts, -1, **(m_2->elts), 1, **(m->elts), 1); 00901 copy_matblock_f(m_out, m); 00902 free_matblock_f(m); 00903 } 00904 else 00905 { 00906 copy_matblock_f(m_out, m_1); 00907 blas_saxpy(num_elts, -1, **(m_2->elts), 1, **((*m_out)->elts), 1); 00908 } 00909 #else 00910 m_1_elts = **(m_1->elts); 00911 m_2_elts = **(m_2->elts); 00912 m_out_elts = **((*m_out)->elts); 00913 00914 if (*m_out == m_1) 00915 { 00916 for (elt = 0; elt < num_elts; elt++) 00917 { 00918 m_1_elts[ elt ] = m_1_elts[ elt ] - m_2_elts[ elt ]; 00919 } 00920 } 00921 else if (*m_out == m_2) 00922 { 00923 for (elt = 0; elt < num_elts; elt++) 00924 { 00925 m_2_elts[ elt ] = m_1_elts[ elt ] - m_2_elts[ elt ]; 00926 } 00927 } 00928 else 00929 { 00930 create_matblock_f(m_out, m_1->num_mats, m_1->num_rows, m_1->num_cols); 00931 for (elt = 0; elt < num_elts; elt++) 00932 { 00933 m_out_elts[ elt ] = m_1_elts[ elt ] - m_2_elts[ elt ]; 00934 } 00935 } 00936 #endif 00937 00938 return NULL; 00939 } 00940 00956 Error* subtract_matblocks_d 00957 ( 00958 Matblock_d** m_out, 00959 const Matblock_d* m_1, 00960 const Matblock_d* m_2 00961 ) 00962 { 00963 uint32_t num_elts; 00964 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00965 Matblock_d* m = NULL; 00966 #else 00967 uint32_t elt; 00968 double* m_1_elts; 00969 double* m_2_elts; 00970 double* m_out_elts; 00971 #endif 00972 00973 if (m_1->num_mats != m_2->num_mats || 00974 m_1->num_rows != m_2->num_rows || 00975 m_1->num_cols != m_2->num_cols) 00976 { 00977 if (*m_out != m_1 && *m_out != m_2) 00978 { 00979 free_matblock_d(*m_out); *m_out = NULL; 00980 } 00981 return JWSC_EARG("Subtracting matblocks requires equal dimensions"); 00982 } 00983 00984 num_elts = m_1->num_mats*m_1->num_rows*m_1->num_cols; 00985 00986 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 00987 if (*m_out == m_1) 00988 { 00989 blas_daxpy(num_elts, -1, **(m_2->elts), 1, **(m_1->elts), 1); 00990 } 00991 else if (*m_out == m_2) 00992 { 00993 copy_matblock_d(&m, m_1); 00994 blas_daxpy(num_elts, -1, **(m_2->elts), 1, **(m->elts), 1); 00995 copy_matblock_d(m_out, m); 00996 free_matblock_d(m); 00997 } 00998 else 00999 { 01000 copy_matblock_d(m_out, m_1); 01001 blas_daxpy(num_elts, -1, **(m_2->elts), 1, **((*m_out)->elts), 1); 01002 } 01003 #else 01004 m_1_elts = **(m_1->elts); 01005 m_2_elts = **(m_2->elts); 01006 m_out_elts = **((*m_out)->elts); 01007 01008 if (*m_out == m_1) 01009 { 01010 for (elt = 0; elt < num_elts; elt++) 01011 { 01012 m_1_elts[ elt ] = m_1_elts[ elt ] - m_2_elts[ elt ]; 01013 } 01014 } 01015 else if (*m_out == m_2) 01016 { 01017 for (elt = 0; elt < num_elts; elt++) 01018 { 01019 m_2_elts[ elt ] = m_1_elts[ elt ] - m_2_elts[ elt ]; 01020 } 01021 } 01022 else 01023 { 01024 create_matblock_d(m_out, m_1->num_mats, m_1->num_rows, m_1->num_cols); 01025 for (elt = 0; elt < num_elts; elt++) 01026 { 01027 m_out_elts[ elt ] = m_1_elts[ elt ] - m_2_elts[ elt ]; 01028 } 01029 } 01030 #endif 01031 01032 return NULL; 01033 } 01034 01051 void calc_matblock_asum_f(float* sum_out, const Matblock_f* m) 01052 { 01053 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 01054 *sum_out = blas_sasum(m->num_mats*m->num_rows*m->num_cols, **(m->elts), 1); 01055 #else 01056 uint32_t num_elts; 01057 uint32_t elt; 01058 float* m_elts; 01059 01060 num_elts = m->num_mats*m->num_rows*m->num_cols; 01061 m_elts = **(m->elts); 01062 *sum_out = 0; 01063 01064 for (elt = 0; elt < num_elts; elt++) 01065 { 01066 (*sum_out) += (float)fabs(m_elts[ elt ]); 01067 } 01068 #endif 01069 } 01070 01075 void calc_matblock_asum_d(double* sum_out, const Matblock_d* m) 01076 { 01077 #if defined JWSC_HAVE_BLAS || defined JWSC_HAVE_ACCELERATE 01078 *sum_out = blas_dasum(m->num_mats*m->num_rows*m->num_cols, **(m->elts), 1); 01079 #else 01080 uint32_t num_elts; 01081 uint32_t elt; 01082 double* m_elts; 01083 01084 num_elts = m->num_mats*m->num_rows*m->num_cols; 01085 m_elts = **(m->elts); 01086 *sum_out = 0; 01087 01088 for (elt = 0; elt < num_elts; elt++) 01089 { 01090 (*sum_out) += fabs(m_elts[ elt ]); 01091 } 01092 #endif 01093 } 01094 01114 void normalize_matblock_sum_f(Matblock_f** m_out, const Matblock_f* m_in) 01115 { 01116 float sum; 01117 01118 calc_matblock_asum_f(&sum, m_in); 01119 01120 if (sum > 0) 01121 { 01122 multiply_matblock_by_scalar_f(m_out, m_in, 1.0f / sum); 01123 } 01124 else 01125 { 01126 copy_matblock_f(m_out, m_in); 01127 } 01128 } 01129 01137 void normalize_matblock_sum_d(Matblock_d** m_out, const Matblock_d* m_in) 01138 { 01139 double sum; 01140 01141 calc_matblock_asum_d(&sum, m_in); 01142 01143 if (sum > 0) 01144 { 01145 multiply_matblock_by_scalar_d(m_out, m_in, 1.0 / sum); 01146 } 01147 else 01148 { 01149 copy_matblock_d(m_out, m_in); 01150 } 01151 } 01152 01170 void abs_matblock_f(Matblock_f** m_out, const Matblock_f* m_in) 01171 { 01172 uint32_t num_elts; 01173 uint32_t elt; 01174 float* m_in_elts; 01175 float* m_out_elts; 01176 01177 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 01178 01179 if (*m_out != m_in) 01180 { 01181 create_matblock_f(m_out, m_in->num_mats, m_in->num_rows, 01182 m_in->num_cols); 01183 } 01184 m_out_elts = **((*m_out)->elts); 01185 m_in_elts = **(m_in->elts); 01186 01187 for (elt = 0; elt < num_elts; elt++) 01188 { 01189 m_out_elts[ elt ] = fabs(m_out_elts[ elt ]); 01190 } 01191 } 01192 01193 01201 void abs_matblock_d(Matblock_d** m_out, const Matblock_d* m_in) 01202 { 01203 uint32_t num_elts; 01204 uint32_t elt; 01205 double* m_in_elts; 01206 double* m_out_elts; 01207 01208 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 01209 01210 if (*m_out != m_in) 01211 { 01212 create_matblock_d(m_out, m_in->num_mats, m_in->num_rows, 01213 m_in->num_cols); 01214 } 01215 m_out_elts = **((*m_out)->elts); 01216 m_in_elts = **(m_in->elts); 01217 01218 for (elt = 0; elt < num_elts; elt++) 01219 { 01220 m_out_elts[ elt ] = fabs(m_out_elts[ elt ]); 01221 } 01222 } 01223 01224 01243 void threshold_matblock_f(Matblock_f** m_out, const Matblock_f* m_in, float threshold) 01244 { 01245 uint32_t num_elts; 01246 uint32_t elt; 01247 float* m_in_elts; 01248 float* m_out_elts; 01249 01250 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 01251 01252 if (*m_out != m_in) 01253 { 01254 create_matblock_f(m_out, m_in->num_mats, m_in->num_rows, 01255 m_in->num_cols); 01256 } 01257 m_out_elts = **((*m_out)->elts); 01258 m_in_elts = **(m_in->elts); 01259 01260 for (elt = 0; elt < num_elts; elt++) 01261 { 01262 if(m_out_elts[ elt ] < threshold) 01263 { 01264 m_out_elts[ elt ] = 0; 01265 } 01266 } 01267 } 01268 01277 void threshold_matblock_d(Matblock_d** m_out, const Matblock_d* m_in, double threshold) 01278 { 01279 uint32_t num_elts; 01280 uint32_t elt; 01281 double * m_in_elts; 01282 double * m_out_elts; 01283 01284 num_elts = m_in->num_mats*m_in->num_rows*m_in->num_cols; 01285 01286 if (*m_out != m_in) 01287 { 01288 create_matblock_d(m_out, m_in->num_mats, m_in->num_rows, 01289 m_in->num_cols); 01290 } 01291 m_out_elts = **((*m_out)->elts); 01292 m_in_elts = **(m_in->elts); 01293 01294 for (elt = 0; elt < num_elts; elt++) 01295 { 01296 if(m_out_elts[ elt ] < threshold) 01297 { 01298 m_out_elts[ elt ] = 0; 01299 } 01300 } 01301 } 01302