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 00050 #include <jwsc/config.h> 00051 00052 #include <stdlib.h> 00053 #include <inttypes.h> 00054 #include <assert.h> 00055 #include <math.h> 00056 #ifdef JWSC_HAVE_FFTW3_H 00057 #include <fftw3.h> 00058 #endif 00059 00060 #include "jwsc/matrix/matrix.h" 00061 #include "jwsc/matrix/matrix_math.h" 00062 00063 00086 #ifdef JWSC_HAVE_FFTW3F 00087 void real_to_complex_matrix_dft_f 00088 ( 00089 Matrix_cf** m_out, 00090 const Matrix_f* m_in 00091 ) 00092 { 00093 uint32_t num_rows, num_cols; 00094 Matrix_f* m_in_copy; 00095 fftwf_plan plan; 00096 00097 num_rows = m_in->num_rows; 00098 num_cols = m_in->num_cols; 00099 00100 create_matrix_cf(m_out, num_rows, (num_cols/2)+1); 00101 00102 /* For fftw planning, input array does not need to be initialized, hence we 00103 * allow fftw to destroy the input to (possibly) get better efficiency. */ 00104 m_in_copy = NULL; 00105 create_matrix_f(&m_in_copy, num_rows, num_cols); 00106 00107 assert((plan = fftwf_plan_dft_r2c_2d(num_rows, num_cols, 00108 *(m_in_copy->elts), (fftwf_complex*)*((*m_out)->elts), 00109 FFTW_MEASURE | FFTW_DESTROY_INPUT)) != NULL); 00110 00111 /* Copy the input, now that planning is over, and execute. */ 00112 copy_matrix_f(&m_in_copy, m_in); 00113 fftwf_execute(plan); 00114 00115 fftwf_destroy_plan(plan); 00116 free_matrix_f(m_in_copy); 00117 } 00118 #endif 00119 00135 #ifdef JWSC_HAVE_FFTW3 00136 void real_to_complex_matrix_dft_d 00137 ( 00138 Matrix_cd** m_out, 00139 const Matrix_d* m_in 00140 ) 00141 { 00142 uint32_t num_rows, num_cols; 00143 Matrix_d* m_in_copy; 00144 fftw_plan plan; 00145 00146 num_rows = m_in->num_rows; 00147 num_cols = m_in->num_cols; 00148 00149 create_matrix_cd(m_out, num_rows, (num_cols/2)+1); 00150 00151 /* For fftw planning, input array does not need to be initialized, hence we 00152 * allow fftw to destroy the input to (possibly) get better efficiency. */ 00153 m_in_copy = NULL; 00154 create_matrix_d(&m_in_copy, num_rows, num_cols); 00155 00156 assert((plan = fftw_plan_dft_r2c_2d(num_rows, num_cols, 00157 *(m_in_copy->elts), (fftw_complex*)*((*m_out)->elts), 00158 FFTW_MEASURE | FFTW_DESTROY_INPUT)) != NULL); 00159 00160 /* Copy the input, now that planning is over, and execute. */ 00161 copy_matrix_d(&m_in_copy, m_in); 00162 fftw_execute(plan); 00163 00164 fftw_destroy_plan(plan); 00165 free_matrix_d(m_in_copy); 00166 } 00167 #endif 00168 00208 #ifdef JWSC_HAVE_FFTW3F 00209 void complex_to_real_matrix_dft_f 00210 ( 00211 Matrix_f** m_out, 00212 const Matrix_cf* m_in, 00213 uint8_t ncols_even 00214 ) 00215 { 00216 uint32_t num_rows, num_cols; 00217 Matrix_cf* m_in_copy; 00218 fftwf_plan plan; 00219 00220 num_rows = m_in->num_rows; 00221 num_cols = (ncols_even) ? (m_in->num_cols-1)*2 : (m_in->num_cols-1)*2 + 1; 00222 00223 create_matrix_f(m_out, num_rows, num_cols); 00224 00225 /* For fftw planning, input array does not need to be initialized, hence we 00226 * allow fftw to destroy the input to (possibly) get better efficiency. */ 00227 m_in_copy = NULL; 00228 create_matrix_cf(&m_in_copy, m_in->num_rows, m_in->num_cols); 00229 00230 assert((plan = fftwf_plan_dft_c2r_2d(num_rows, num_cols, 00231 (fftwf_complex*)*(m_in_copy->elts), *((*m_out)->elts), 00232 FFTW_MEASURE | FFTW_DESTROY_INPUT)) != NULL); 00233 00234 /* Copy the input, now that planning is over, and execute. */ 00235 copy_matrix_cf(&m_in_copy, m_in); 00236 fftwf_execute(plan); 00237 00238 fftwf_destroy_plan(plan); 00239 free_matrix_cf(m_in_copy); 00240 } 00241 #endif 00242 00270 #ifdef JWSC_HAVE_FFTW3 00271 void complex_to_real_matrix_dft_d 00272 ( 00273 Matrix_d** m_out, 00274 const Matrix_cd* m_in, 00275 uint8_t ncols_even 00276 ) 00277 { 00278 uint32_t num_rows, num_cols; 00279 Matrix_cd* m_in_copy; 00280 fftw_plan plan; 00281 00282 num_rows = m_in->num_rows; 00283 num_cols = (ncols_even) ? (m_in->num_cols-1)*2 : (m_in->num_cols-1)*2 + 1; 00284 00285 create_matrix_d(m_out, num_rows, num_cols); 00286 00287 /* For fftw planning, input array does not need to be initialized, hence we 00288 * allow fftw to destroy the input to (possibly) get better efficiency. */ 00289 m_in_copy = NULL; 00290 create_matrix_cd(&m_in_copy, m_in->num_rows, m_in->num_cols); 00291 00292 assert((plan = fftw_plan_dft_c2r_2d(num_rows, num_cols, 00293 (fftw_complex*)*(m_in_copy->elts), *((*m_out)->elts), 00294 FFTW_MEASURE | FFTW_DESTROY_INPUT)) != NULL); 00295 00296 /* Copy the input, now that planning is over, and execute. */ 00297 copy_matrix_cd(&m_in_copy, m_in); 00298 fftw_execute(plan); 00299 00300 fftw_destroy_plan(plan); 00301 free_matrix_cd(m_in_copy); 00302 } 00303 #endif 00304 00326 void expand_symmetric_matrix_dft_f 00327 ( 00328 Matrix_cf** m_out, 00329 const Matrix_cf* m_in, 00330 uint8_t ncols_even 00331 ) 00332 { 00333 uint32_t num_rows, num_cols; 00334 uint32_t row, col; 00335 Matrix_cf* m; 00336 00337 num_rows = m_in->num_rows; 00338 num_cols = m_in->num_cols; 00339 00340 m = (*m_out == m_in) ? NULL : *m_out; 00341 if (ncols_even) 00342 { 00343 create_matrix_cf(&m, num_rows, (m_in->num_cols-1)*2); 00344 } 00345 else 00346 { 00347 create_matrix_cf(&m, num_rows, (m_in->num_cols-1)*2 + 1); 00348 } 00349 00350 assert(copy_matrix_block_into_matrix_cf(m, 0, 0, m_in, 0, 0, 00351 m_in->num_rows, m_in->num_cols) == NULL); 00352 00353 for (row = 0; row < num_rows; row++) 00354 { 00355 for (col = m->num_cols-1; col >= m_in->num_cols; col--) 00356 { 00357 m->elts[row][col] = m_in->elts[row][m->num_cols-col-1]; 00358 } 00359 } 00360 00361 if (*m_out == m_in) 00362 { 00363 copy_matrix_cf(m_out, m); 00364 free_matrix_cf(m); 00365 } 00366 else 00367 { 00368 *m_out = m; 00369 } 00370 } 00371 00381 void expand_symmetric_matrix_dft_d 00382 ( 00383 Matrix_cd** m_out, 00384 const Matrix_cd* m_in, 00385 uint8_t ncols_even 00386 ) 00387 { 00388 uint32_t num_rows, num_cols; 00389 uint32_t row, col; 00390 Matrix_cd* m; 00391 00392 num_rows = m_in->num_rows; 00393 num_cols = m_in->num_cols; 00394 00395 m = (*m_out == m_in) ? NULL : *m_out; 00396 if (ncols_even) 00397 { 00398 create_matrix_cd(&m, num_rows, (m_in->num_cols-1)*2); 00399 } 00400 else 00401 { 00402 create_matrix_cd(&m, num_rows, (m_in->num_cols-1)*2 + 1); 00403 } 00404 00405 assert(copy_matrix_block_into_matrix_cd(m, 0, 0, m_in, 0, 0, 00406 m_in->num_rows, m_in->num_cols) == NULL); 00407 00408 for (row = 0; row < num_rows; row++) 00409 { 00410 for (col = m->num_cols-1; col >= m_in->num_cols; col--) 00411 { 00412 m->elts[row][col] = m_in->elts[row][m->num_cols-col-1]; 00413 } 00414 } 00415 00416 if (*m_out == m_in) 00417 { 00418 copy_matrix_cd(m_out, m); 00419 free_matrix_cd(m); 00420 } 00421 else 00422 { 00423 *m_out = m; 00424 } 00425 } 00426 00446 void shrink_symmetric_matrix_dft_f(Matrix_cf** m_out, const Matrix_cf* m_in) 00447 { 00448 Matrix_cf* m; 00449 00450 m = (*m_out == m_in) ? NULL : *m_out; 00451 create_matrix_cf(&m, m_in->num_rows, (m_in->num_cols/2)+1); 00452 00453 assert(copy_matrix_block_into_matrix_cf(m, 0, 0, m_in, 0, 0, 00454 m->num_rows, m->num_cols) == NULL); 00455 00456 if (*m_out == m_in) 00457 { 00458 copy_matrix_cf(m_out, m); 00459 free_matrix_cf(m); 00460 } 00461 else 00462 { 00463 *m_out = m; 00464 } 00465 } 00466 00474 void shrink_symmetric_matrix_dft_d(Matrix_cd** m_out, const Matrix_cd* m_in) 00475 { 00476 Matrix_cd* m; 00477 00478 m = (*m_out == m_in) ? NULL : *m_out; 00479 create_matrix_cd(&m, m_in->num_rows, (m_in->num_cols/2)+1); 00480 00481 assert(copy_matrix_block_into_matrix_cd(m, 0, 0, m_in, 0, 0, 00482 m->num_rows, m->num_cols) == NULL); 00483 00484 if (*m_out == m_in) 00485 { 00486 copy_matrix_cd(m_out, m); 00487 free_matrix_cd(m); 00488 } 00489 else 00490 { 00491 *m_out = m; 00492 } 00493 } 00494 00518 void scale_matrix_dft_f(Matrix_f** m_out, const Matrix_f* m_in) 00519 { 00520 float scale; 00521 00522 scale = 1.0f / (float)(m_in->num_rows*m_in->num_cols); 00523 multiply_matrix_by_scalar_f(m_out, m_in, scale); 00524 } 00525 00537 void scale_matrix_dft_d(Matrix_d** m_out, const Matrix_d* m_in) 00538 { 00539 float scale; 00540 00541 scale = 1.0 / (double)(m_in->num_rows*m_in->num_cols); 00542 multiply_matrix_by_scalar_d(m_out, m_in, scale); 00543 } 00544 00566 void shift_matrix_f 00567 ( 00568 Matrix_f** m_out, 00569 const Matrix_f* m_in 00570 ) 00571 { 00572 uint32_t num_rows, num_cols; 00573 uint32_t row, col; 00574 uint32_t half_rows, half_cols; 00575 00576 Matrix_f* m = NULL; 00577 00578 num_rows = m_in->num_rows; 00579 num_cols = m_in->num_cols; 00580 half_rows = num_rows / 2; 00581 half_cols = num_cols / 2; 00582 00583 m = (*m_out == m_in) ? NULL : *m_out; 00584 create_matrix_f(&m, num_rows, num_cols); 00585 00586 for (row = 0; row < num_rows; row++) 00587 { 00588 if (row < half_rows + (num_rows % 2)) 00589 { 00590 for (col = 0; col < num_cols; col++) 00591 { 00592 if (col < half_cols + (num_cols % 2)) 00593 { 00594 m->elts[ row ][ col ] = m_in->elts 00595 [ row + half_rows ] 00596 [ col + half_cols ]; 00597 } 00598 else 00599 { 00600 m->elts[ row ][ col ] = m_in->elts 00601 [ row + half_rows ] 00602 [ col-half_cols-(num_cols % 2) ]; 00603 } 00604 } 00605 } 00606 else 00607 { 00608 for (col = 0; col < num_cols; col++) 00609 { 00610 if (col < half_cols + (num_cols % 2)) 00611 { 00612 m->elts[ row ][ col ] = m_in->elts 00613 [ row - half_rows - (num_rows % 2) ] 00614 [ col + half_cols ]; 00615 } 00616 else 00617 { 00618 m->elts[ row ][ col ] = m_in->elts 00619 [ row - half_rows - (num_rows % 2) ] 00620 [ col - half_cols - (num_cols % 2) ]; 00621 } 00622 } 00623 } 00624 } 00625 00626 if (*m_out == m_in) 00627 { 00628 copy_matrix_f(m_out, m); 00629 free_matrix_f(m); 00630 } 00631 else 00632 { 00633 *m_out = m; 00634 } 00635 } 00636 00646 void shift_matrix_d 00647 ( 00648 Matrix_d** m_out, 00649 const Matrix_d* m_in 00650 ) 00651 { 00652 uint32_t num_rows, num_cols; 00653 uint32_t row, col; 00654 uint32_t half_rows, half_cols; 00655 00656 Matrix_d* m = NULL; 00657 00658 num_rows = m_in->num_rows; 00659 num_cols = m_in->num_cols; 00660 half_rows = num_rows / 2; 00661 half_cols = num_cols / 2; 00662 00663 m = (*m_out == m_in) ? NULL : *m_out; 00664 create_matrix_d(&m, num_rows, num_cols); 00665 00666 for (row = 0; row < num_rows; row++) 00667 { 00668 if (row < half_rows + (num_rows % 2)) 00669 { 00670 for (col = 0; col < num_cols; col++) 00671 { 00672 if (col < half_cols + (num_cols % 2)) 00673 { 00674 m->elts[ row ][ col ] = m_in->elts 00675 [ row + half_rows ] 00676 [ col + half_cols ]; 00677 } 00678 else 00679 { 00680 m->elts[ row ][ col ] = m_in->elts 00681 [ row + half_rows ] 00682 [ col-half_cols-(num_cols % 2) ]; 00683 } 00684 } 00685 } 00686 else 00687 { 00688 for (col = 0; col < num_cols; col++) 00689 { 00690 if (col < half_cols + (num_cols % 2)) 00691 { 00692 m->elts[ row ][ col ] = m_in->elts 00693 [ row - half_rows - (num_rows % 2) ] 00694 [ col + half_cols ]; 00695 } 00696 else 00697 { 00698 m->elts[ row ][ col ] = m_in->elts 00699 [ row - half_rows - (num_rows % 2) ] 00700 [ col - half_cols - (num_cols % 2) ]; 00701 } 00702 } 00703 } 00704 } 00705 00706 if (*m_out == m_in) 00707 { 00708 copy_matrix_d(m_out, m); 00709 free_matrix_d(m); 00710 } 00711 else 00712 { 00713 *m_out = m; 00714 } 00715 } 00716 00726 void shift_matrix_cf 00727 ( 00728 Matrix_cf** m_out, 00729 const Matrix_cf* m_in 00730 ) 00731 { 00732 uint32_t num_rows, num_cols; 00733 uint32_t row, col; 00734 uint32_t half_rows, half_cols; 00735 00736 Matrix_cf* m = NULL; 00737 00738 num_rows = m_in->num_rows; 00739 num_cols = m_in->num_cols; 00740 half_rows = num_rows / 2; 00741 half_cols = num_cols / 2; 00742 00743 m = (*m_out == m_in) ? NULL : *m_out; 00744 create_matrix_cf(&m, num_rows, num_cols); 00745 00746 for (row = 0; row < num_rows; row++) 00747 { 00748 if (row < half_rows + (num_rows % 2)) 00749 { 00750 for (col = 0; col < num_cols; col++) 00751 { 00752 if (col < half_cols + (num_cols % 2)) 00753 { 00754 m->elts[ row ][ col ] = m_in->elts 00755 [ row + half_rows ] 00756 [ col + half_cols ]; 00757 } 00758 else 00759 { 00760 m->elts[ row ][ col ] = m_in->elts 00761 [ row + half_rows ] 00762 [ col-half_cols-(num_cols % 2) ]; 00763 } 00764 } 00765 } 00766 else 00767 { 00768 for (col = 0; col < num_cols; col++) 00769 { 00770 if (col < half_cols + (num_cols % 2)) 00771 { 00772 m->elts[ row ][ col ] = m_in->elts 00773 [ row - half_rows - (num_rows % 2) ] 00774 [ col + half_cols ]; 00775 } 00776 else 00777 { 00778 m->elts[ row ][ col ] = m_in->elts 00779 [ row - half_rows - (num_rows % 2) ] 00780 [ col - half_cols - (num_cols % 2) ]; 00781 } 00782 } 00783 } 00784 } 00785 00786 if (*m_out == m_in) 00787 { 00788 copy_matrix_cf(m_out, m); 00789 free_matrix_cf(m); 00790 } 00791 else 00792 { 00793 *m_out = m; 00794 } 00795 } 00796 00806 void shift_matrix_cd 00807 ( 00808 Matrix_cd** m_out, 00809 const Matrix_cd* m_in 00810 ) 00811 { 00812 uint32_t num_rows, num_cols; 00813 uint32_t row, col; 00814 uint32_t half_rows, half_cols; 00815 00816 Matrix_cd* m = NULL; 00817 00818 num_rows = m_in->num_rows; 00819 num_cols = m_in->num_cols; 00820 half_rows = num_rows / 2; 00821 half_cols = num_cols / 2; 00822 00823 m = (*m_out == m_in) ? NULL : *m_out; 00824 create_matrix_cd(&m, num_rows, num_cols); 00825 00826 for (row = 0; row < num_rows; row++) 00827 { 00828 if (row < half_rows + (num_rows % 2)) 00829 { 00830 for (col = 0; col < num_cols; col++) 00831 { 00832 if (col < half_cols + (num_cols % 2)) 00833 { 00834 m->elts[ row ][ col ] = m_in->elts 00835 [ row + half_rows ] 00836 [ col + half_cols ]; 00837 } 00838 else 00839 { 00840 m->elts[ row ][ col ] = m_in->elts 00841 [ row + half_rows ] 00842 [ col-half_cols-(num_cols % 2) ]; 00843 } 00844 } 00845 } 00846 else 00847 { 00848 for (col = 0; col < num_cols; col++) 00849 { 00850 if (col < half_cols + (num_cols % 2)) 00851 { 00852 m->elts[ row ][ col ] = m_in->elts 00853 [ row - half_rows - (num_rows % 2) ] 00854 [ col + half_cols ]; 00855 } 00856 else 00857 { 00858 m->elts[ row ][ col ] = m_in->elts 00859 [ row - half_rows - (num_rows % 2) ] 00860 [ col - half_cols - (num_cols % 2) ]; 00861 } 00862 } 00863 } 00864 } 00865 00866 if (*m_out == m_in) 00867 { 00868 copy_matrix_cd(m_out, m); 00869 free_matrix_cd(m); 00870 } 00871 else 00872 { 00873 *m_out = m; 00874 } 00875 } 00876 00898 void unshift_matrix_f 00899 ( 00900 Matrix_f** m_out, 00901 const Matrix_f* m_in 00902 ) 00903 { 00904 uint32_t num_rows, num_cols; 00905 uint32_t row, col; 00906 uint32_t half_rows, half_cols; 00907 00908 Matrix_f* m = NULL; 00909 00910 num_rows = m_in->num_rows; 00911 num_cols = m_in->num_cols; 00912 half_rows = num_rows / 2; 00913 half_cols = num_cols / 2; 00914 00915 m = (*m_out == m_in) ? NULL : *m_out; 00916 create_matrix_f(&m, num_rows, num_cols); 00917 00918 for (row = 0; row < num_rows; row++) 00919 { 00920 if (row < half_rows) 00921 { 00922 for (col = 0; col < num_cols; col++) 00923 { 00924 if (col < half_cols) 00925 { 00926 m->elts[ row ][ col ] = m_in->elts 00927 [ row + half_rows + (num_rows % 2) ] 00928 [ col + half_cols + (num_cols % 2) ]; 00929 } 00930 else 00931 { 00932 m->elts[ row ][ col ] = m_in->elts 00933 [ row + half_rows + (num_rows % 2) ] 00934 [ col - half_cols ]; 00935 } 00936 } 00937 } 00938 else 00939 { 00940 for (col = 0; col < num_cols; col++) 00941 { 00942 if (col < half_cols) 00943 { 00944 m->elts[ row ][ col ] = m_in->elts 00945 [ row - half_rows ] 00946 [ col + half_cols + (num_cols % 2) ]; 00947 } 00948 else 00949 { 00950 m->elts[ row ][ col ] = m_in->elts 00951 [ row - half_rows] 00952 [ col - half_cols]; 00953 } 00954 } 00955 } 00956 } 00957 00958 if (*m_out == m_in) 00959 { 00960 copy_matrix_f(m_out, m); 00961 free_matrix_f(m); 00962 } 00963 else 00964 { 00965 *m_out = m; 00966 } 00967 } 00968 00978 void unshift_matrix_d 00979 ( 00980 Matrix_d** m_out, 00981 const Matrix_d* m_in 00982 ) 00983 { 00984 uint32_t num_rows, num_cols; 00985 uint32_t row, col; 00986 uint32_t half_rows, half_cols; 00987 00988 Matrix_d* m = NULL; 00989 00990 num_rows = m_in->num_rows; 00991 num_cols = m_in->num_cols; 00992 half_rows = num_rows / 2; 00993 half_cols = num_cols / 2; 00994 00995 m = (*m_out == m_in) ? NULL : *m_out; 00996 create_matrix_d(&m, num_rows, num_cols); 00997 00998 for (row = 0; row < num_rows; row++) 00999 { 01000 if (row < half_rows) 01001 { 01002 for (col = 0; col < num_cols; col++) 01003 { 01004 if (col < half_cols) 01005 { 01006 m->elts[ row ][ col ] = m_in->elts 01007 [ row + half_rows + (num_rows % 2) ] 01008 [ col + half_cols + (num_cols % 2) ]; 01009 } 01010 else 01011 { 01012 m->elts[ row ][ col ] = m_in->elts 01013 [ row + half_rows + (num_rows % 2) ] 01014 [ col - half_cols ]; 01015 } 01016 } 01017 } 01018 else 01019 { 01020 for (col = 0; col < num_cols; col++) 01021 { 01022 if (col < half_cols) 01023 { 01024 m->elts[ row ][ col ] = m_in->elts 01025 [ row - half_rows ] 01026 [ col + half_cols + (num_cols % 2) ]; 01027 } 01028 else 01029 { 01030 m->elts[ row ][ col ] = m_in->elts 01031 [ row - half_rows] 01032 [ col - half_cols]; 01033 } 01034 } 01035 } 01036 } 01037 01038 if (*m_out == m_in) 01039 { 01040 copy_matrix_d(m_out, m); 01041 free_matrix_d(m); 01042 } 01043 else 01044 { 01045 *m_out = m; 01046 } 01047 } 01048 01058 void unshift_matrix_cf 01059 ( 01060 Matrix_cf** m_out, 01061 const Matrix_cf* m_in 01062 ) 01063 { 01064 uint32_t num_rows, num_cols; 01065 uint32_t row, col; 01066 uint32_t half_rows, half_cols; 01067 01068 Matrix_cf* m = NULL; 01069 01070 num_rows = m_in->num_rows; 01071 num_cols = m_in->num_cols; 01072 half_rows = num_rows / 2; 01073 half_cols = num_cols / 2; 01074 01075 m = (*m_out == m_in) ? NULL : *m_out; 01076 create_matrix_cf(&m, num_rows, num_cols); 01077 01078 for (row = 0; row < num_rows; row++) 01079 { 01080 if (row < half_rows) 01081 { 01082 for (col = 0; col < num_cols; col++) 01083 { 01084 if (col < half_cols) 01085 { 01086 m->elts[ row ][ col ] = m_in->elts 01087 [ row + half_rows + (num_rows % 2) ] 01088 [ col + half_cols + (num_cols % 2) ]; 01089 } 01090 else 01091 { 01092 m->elts[ row ][ col ] = m_in->elts 01093 [ row + half_rows + (num_rows % 2) ] 01094 [ col - half_cols ]; 01095 } 01096 } 01097 } 01098 else 01099 { 01100 for (col = 0; col < num_cols; col++) 01101 { 01102 if (col < half_cols) 01103 { 01104 m->elts[ row ][ col ] = m_in->elts 01105 [ row - half_rows ] 01106 [ col + half_cols + (num_cols % 2) ]; 01107 } 01108 else 01109 { 01110 m->elts[ row ][ col ] = m_in->elts 01111 [ row - half_rows] 01112 [ col - half_cols]; 01113 } 01114 } 01115 } 01116 } 01117 01118 if (*m_out == m_in) 01119 { 01120 copy_matrix_cf(m_out, m); 01121 free_matrix_cf(m); 01122 } 01123 else 01124 { 01125 *m_out = m; 01126 } 01127 } 01128 01138 void unshift_matrix_cd 01139 ( 01140 Matrix_cd** m_out, 01141 const Matrix_cd* m_in 01142 ) 01143 { 01144 uint32_t num_rows, num_cols; 01145 uint32_t row, col; 01146 uint32_t half_rows, half_cols; 01147 01148 Matrix_cd* m = NULL; 01149 01150 num_rows = m_in->num_rows; 01151 num_cols = m_in->num_cols; 01152 half_rows = num_rows / 2; 01153 half_cols = num_cols / 2; 01154 01155 m = (*m_out == m_in) ? NULL : *m_out; 01156 create_matrix_cd(&m, num_rows, num_cols); 01157 01158 for (row = 0; row < num_rows; row++) 01159 { 01160 if (row < half_rows) 01161 { 01162 for (col = 0; col < num_cols; col++) 01163 { 01164 if (col < half_cols) 01165 { 01166 m->elts[ row ][ col ] = m_in->elts 01167 [ row + half_rows + (num_rows % 2) ] 01168 [ col + half_cols + (num_cols % 2) ]; 01169 } 01170 else 01171 { 01172 m->elts[ row ][ col ] = m_in->elts 01173 [ row + half_rows + (num_rows % 2) ] 01174 [ col - half_cols ]; 01175 } 01176 } 01177 } 01178 else 01179 { 01180 for (col = 0; col < num_cols; col++) 01181 { 01182 if (col < half_cols) 01183 { 01184 m->elts[ row ][ col ] = m_in->elts 01185 [ row - half_rows ] 01186 [ col + half_cols + (num_cols % 2) ]; 01187 } 01188 else 01189 { 01190 m->elts[ row ][ col ] = m_in->elts 01191 [ row - half_rows] 01192 [ col - half_cols]; 01193 } 01194 } 01195 } 01196 } 01197 01198 if (*m_out == m_in) 01199 { 01200 copy_matrix_cd(m_out, m); 01201 free_matrix_cd(m); 01202 } 01203 else 01204 { 01205 *m_out = m; 01206 } 01207 } 01208