pax_global_header00006660000000000000000000000064135304674610014523gustar00rootroot0000000000000052 comment=5efc0a95bbce5cc274a7c5ec3bb95ea0db6e67be bart-0.5.00/000077500000000000000000000000001353046746100125355ustar00rootroot00000000000000bart-0.5.00/.gitignore.main000066400000000000000000000007441353046746100154550ustar00rootroot00000000000000 # autogenerated .gitignore files .gitignore # dependency files *.d # object files *.o # mac debug files *.dSYM # python compiled files *.pyc python/.ipynb_checkpoints/ # temporary files .*.swp *~ # local Makefile Makefile.local # version string src/misc/version.inc # noise simulations save/nsv/*.dat # fftw wisdoms save/fftw/*.fftw # ctags tags GTAGS GSYMS GRTAGS GPATH # autogenerated documentation doc/html doc/latex doc/dx doc/commands.txt # test files tests/test-* bart-0.5.00/.travis.yml000066400000000000000000000074531353046746100146570ustar00rootroot00000000000000language: c env: addons: apt: packages: &default_packages - libfftw3-dev - libblas-dev - libpng-dev matrix: allow_failures: - env: MAYFAIL=1 include: - name: "Makefile PARALLEL" env: PARALLEL=1 os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - liblapacke-dev - name: "Makefile + test + utest" env: os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - liblapacke-dev script: - make test - make utest - name: "Makefile Clang" env: OMP=0 os: linux compiler: clang sudo: required dist: trusty addons: apt: packages: - *default_packages - liblapacke-dev - libblocksruntime-dev script: - make utest - name: "Makefile OpenMP" env: OMP=1 os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - liblapacke-dev script: - make test - make utest - name: "Makefile NOLAPACKE" env: NOLAPACKE=1 os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - gfortran - liblapack-dev - name: "CMake GCC-5" env: MAYFAIL=1 os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - libatlas-base-dev - liblapacke-dev before_script: - mkdir build && cd build # NB: CC is automatically set to `compiler` by Travis - cmake .. -DLINALG_VENDOR=ATLAS -DBART_ENABLE_MEM_CFL=OFF -DBUILD_TESTING=OFF -DBART_LOG_BACKEND=OFF -DUSE_OPENMP=ON -DBART_GENERATE_DOC=OFF - name: "CMake GCC-5 NOLAPACKE" env: MAYFAIL=1 os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - gfortran - libatlas-base-dev - liblapack-dev before_script: - mkdir build && cd build # NB: CC is automatically set to `compiler` by Travis - cmake .. -DBART_ENABLE_MEM_CFL=OFF -DBUILD_TESTING=OFF -DBART_LOG_BACKEND=OFF -DUSE_OPENMP=ON -DBART_GENERATE_DOC=OFF -DBART_NO_LAPACKE=ON - name: "CMake GCC-5/G++-5 (with mem-CFL support) + utest" env: MAYFAIL=1 os: linux compiler: gcc-5 sudo: required dist: trusty addons: apt: sources: - ubuntu-toolchain-r-test packages: - *default_packages - gcc-5 - g++-5 - libatlas-base-dev - liblapacke-dev before_script: - mkdir build && cd build # NB: CC is automatically set to `compiler` by Travis - CXX=g++-5 cmake .. -DLINALG_VENDOR=ATLAS -DBART_ENABLE_MEM_CFL=ON -DBUILD_TESTING=ON -DBART_LOG_BACKEND=OFF -DUSE_OPENMP=ON -DBART_GENERATE_DOC=OFF after_script: - make test script: - make bart - make all bart-0.5.00/ACKNOWLEDGEMENTS000066400000000000000000000011211353046746100150050ustar00rootroot00000000000000 We want to acknowledge the following persons for supporting BART by contributing source code, testing, feedback, data, bug reports, etc. (alphabetrical) Marcus T. Alley Michael Anderson Jakob Asslaender Dara Bahri Soumick Chatterjee Joseph Y. Cheng Sofia Dimoudi Siddharth Iyer Hans Johnson Christian Holme Gregory R. Lee Evan G. Levine Tim Loderhose Michael Lustig Lyu Mengye Damien Nguyen Frank Ong Sebastian Rosenzweig Nick Scholand David Smith Jonathan I. Tamir Michelle Tamir (logo) Johannes Toger Martin Uecker Shreyas S. Vasanawala Sana Vaziri Patrick Virtue Simon Yeung Tao Zhang bart-0.5.00/CMakeLists.txt000066400000000000000000000463161353046746100153070ustar00rootroot00000000000000# Copyright 2015-2016. Hans J. Johnson # Copyright 2017-2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Hans J. Johnson # \author Damien Nguyen cmake_minimum_required(VERSION 2.8.12) if(CMAKE_VERSION VERSION_GREATER 3.0) set(_policy_list CMP0012 CMP0028 CMP0042 CMP0048 CMP0051 CMP0054 CMP0057 CMP0074) foreach(_policy ${_policy_list}) if(POLICY ${_policy}) cmake_policy(SET ${_policy} NEW) endif() endforeach() # CMP0012: if() recognizes numbers and booleans # CMP0028: :: in target names # CMP0042: MACOS_RPATH # CMP0048: allow VERSION in project() # CMP0051: list TARGET_OBJECTS in SOURCES property # CMP0054: no more de-referencing of "expr" in if() statements # CMP0057: if IN_LIST # CMP0074: XXX_ROOT variables for find_package(XXX) endif() if(CMAKE_VERSION VERSION_LESS 3.10) # 3.10 instead of 3.3 due to CUDA support if(CMAKE_VERSION VERSION_GREATER 3.8.99) message(STATUS "From the BART maintainers: ignore the message below") endif() cmake_policy(SET CMP0023 OLD) # target_link_libraries mixed signatures else() cmake_policy(SET CMP0023 NEW) # target_link_libraries mixed signatures endif() # ============================================================================== # Internal helper variables set(_compile_flags_c) set(_compile_flags_cxx) set(_compile_flags_c_release) set(_compile_flags_cxx_release) # ============================================================================== # Macro definitions include(${CMAKE_CURRENT_LIST_DIR}/cmake/bart_macros.cmake) # ============================================================================== # Get the version now, so that we can set it when creating the project if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/.git) find_package(Git QUIET) if(Git_FOUND) execute_process( COMMAND ${GIT_EXECUTABLE} describe --match "v*" --dirty OUTPUT_VARIABLE _full_version RESULT_VARIABLE _ret WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) if(_ret EQUAL 0) string(STRIP ${_full_version} _full_version) # _full_version is of the form: v0.4.03-109-gf9c0f56-dirty string(REGEX MATCHALL "[0-9]+" _version_list ${_full_version}) list(GET _version_list 0 _version_major) list(GET _version_list 1 _version_minor) list(GET _version_list 2 _version_patch) file(WRITE ${CMAKE_CURRENT_LIST_DIR}/version.txt "v${_version_major}.${_version_minor}.${_version_patch}\n") else() get_version_from_file(${CMAKE_CURRENT_LIST_DIR}/version.txt) endif() else() get_version_from_file(${CMAKE_CURRENT_LIST_DIR}/version.txt) endif() else() get_version_from_file(${CMAKE_CURRENT_LIST_DIR}/version.txt) endif() # ============================================================================== # Create the BART project if(CMAKE_VERSION VERSION_LESS 3.0) project(BART C) set(PROJECT_VERSION_MAJOR ${_version_major}) set(PROJECT_VERSION_MINOR ${_version_minor}) set(PROJECT_VERSION_PATCH ${_version_patch}) set(${CMAKE_PROJECT_NAME}_VERSION_MAJOR ${_version_major}) set(${CMAKE_PROJECT_NAME}_VERSION_MINOR ${_version_minor}) set(${CMAKE_PROJECT_NAME}_VERSION_PATCH ${_version_patch}) else() project(BART LANGUAGES C VERSION "${_version_major}.${_version_minor}.${_version_patch}") endif() # Set a default build type if none was specified if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Release' as none was specified.") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo") endif() list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_LIST_DIR}/cmake) #============================================================================== # Options # NB: must be before compiler flags since we might enable CXX or CUDA include(${CMAKE_CURRENT_LIST_DIR}/cmake/bart_options.cmake) #============================================================================== # Setup compiler flags # http://stackoverflow.com/questions/24840030/forcing-c99-in-cmake-to-use-for-loop-initial-declaration if (CMAKE_VERSION VERSION_LESS 3.1) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set (CMAKE_C_FLAGS "--std=gnu11 ${CMAKE_C_FLAGS}") endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set (CMAKE_CXX_FLAGS "--std=c++14 ${CMAKE_CXX_FLAGS}") endif() else() set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() # ============================================================================== # --- Provide good defaults for searching for packages (i.e. ismrmrd) if(NOT CMAKE_PREFIX_PATH) list(APPEND CMAKE_PREFIX_PATH "/usr/local") endif() if(EXISTS $ENV{CMAKE_PREFIX_PATH}) list(APPEND CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH}) endif() if(EXISTS $ENV{ISMRMRD_HOME}) list(APPEND CMAKE_PREFIX_PATH $ENV{ISMRMRD_HOME}) endif() if(CMAKE_PREFIX_PATH) list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) endif() # --- Mac specific setup options if(APPLE) # Look for MacPorts only as Homebrew users do not require any particular setup find_program(MACPORTS NAMES port PATHS /opt/local/bin /opt/local/sbin) if(MACPORTS) add_definitions(-DUSE_MACPORTS) endif() endif() # ============================================================================== # Set compiler flags check_for_compiler_flags(_compile_flags_release "-ffast-math /fp:fast -fast" "-O3 /Ox" ) if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") list(APPEND _compile_flags_c "-fblocks") list(APPEND _compile_flags_cxx "-fblocks") endif() if(CMAKE_VERSION VERSION_GREATER 3.2.99) add_compile_options( "$<$:${_compile_flags_c}>" "$<$,$>:${_compile_flags_release_c}>" ) if(CMAKE_CXX_COMPILER_LOADED) add_compile_options( "$<$:${_compile_flags_cxx}>" "$<$,$>:${_compile_flags_release_cxx}>" ) endif() else() foreach(_flag ${_compile_flags_c}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}") endforeach() foreach(_flag ${_compile_flags_c_release}) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${_flag}") endforeach() if(CMAKE_CXX_COMPILER_LOADED) foreach(_flag ${_compile_flags_cxx}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}") endforeach() foreach(_flag ${_compile_flags_cxx_release}) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${_flag}") endforeach() endif() endif() set(CMAKE_DEBUG_POSTFIX "d") set(CMAKE_RELWITHDEBINFO_POSTFIX "rd") set(CMAKE_MINSIZEREL_POSTFIX "rm") # ============================================================================== # Find a BLAS-capable library include(${CMAKE_CURRENT_LIST_DIR}/cmake/BARTFindBLASlib.cmake) ##====================================================================== if(DEFINED _full_version) set(BART_FULL_VERSION_STRING ${_full_version}) else() set(BART_FULL_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") endif() file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/version.inc.in "VERSION(\@BART_FULL_VERSION_STRING\@)") configure_file(${CMAKE_CURRENT_BINARY_DIR}/version.inc.in ${CMAKE_CURRENT_BINARY_DIR}/version.inc @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR}) ## ========== Process build_targets.mk set (ALLPROGS "") file(READ "${CMAKE_CURRENT_LIST_DIR}/build_targets.mk" bld_tgt_list_of_list) # Convert file contents into a CMake list (where each element in the list # is one line of the file) # string(REGEX REPLACE ";" "\\\\;" bld_tgt_list_of_list "${bld_tgt_list_of_list}") string(REGEX REPLACE "\n" ";" bld_tgt_list_of_list "${bld_tgt_list_of_list}") foreach(bld_tgt_line ${bld_tgt_list_of_list}) if( "${bld_tgt_line}" MATCHES "^[^#].*=.*") string(REGEX REPLACE "^ *([^=]*) *= *(.*) *" "\\1" BLD_KEY "${bld_tgt_line}") string(REGEX REPLACE "^ *([^=]*) *= *(.*) *" "\\2" BLD_VALUE "${bld_tgt_line}") string(REPLACE " " ";" ${BLD_KEY} "${BLD_VALUE}") ## Create a new variable called ${BLD_KEY} ## message(STATUS "KEY:${BLD_KEY}: VALUE:${${BLD_KEY}}:") list(APPEND ALLPROGS ${${BLD_KEY}}) endif() endforeach() if(DEFINED BART_EXTRA_PROGS) list(APPEND ALLPROGS ${BART_EXTRA_PROGS}) endif() if(BART_ISMRMRD) list(APPEND ALLPROGS ismrmrd) endif() if(BART_DISABLE_PNG) list(REMOVE_ITEM ALLPROGS "toimg") endif() list(SORT ALLPROGS) set(BART_SUPPORT_LIBS) file(GLOB support_libs ${CMAKE_CURRENT_LIST_DIR}/src/*) foreach(_f ${support_libs}) if(IS_DIRECTORY ${_f}) get_filename_component(_name ${_f} NAME) if(NOT "${_name}" STREQUAL "python") list(APPEND BART_SUPPORT_LIBS ${_name}) endif() endif() endforeach() if(BART_ISMRMRD) link_directories(${ISMRMRD_LIBRARY_DIRS}) include_directories(${ISMRMRD_INCLUDE_DIRS}) else() list(REMOVE_ITEM BART_SUPPORT_LIBS ismrm) endif() if(NOT BART_NO_LAPACKE) list(REMOVE_ITEM BART_SUPPORT_LIBS lapacke) endif() include_directories(${CMAKE_CURRENT_LIST_DIR}/src) set(bart_support_SRCS "") set(bart_support_CCSRCS "") set(bart_support_CUSRCS "") foreach(curr_lib ${BART_SUPPORT_LIBS}) file(GLOB ${curr_lib}_SRCS "src/${curr_lib}/*.c") list(APPEND bart_support_SRCS ${${curr_lib}_SRCS}) file(GLOB ${curr_lib}_CCSRCS "src/${curr_lib}/*.cc") list(APPEND bart_support_SRCS ${${curr_lib}_CCSRCS}) file(GLOB ${curr_lib}_CUSRCS "src/${curr_lib}/*.cu") list(APPEND bart_support_CUSRCS ${${curr_lib}_CUSRCS}) endforeach() # ------------------------------------------------------------------------------ # These files need to be compiled separately since they might contain # Python code set(BARTSUPPORT_PYTHON_SEPARATE_COMPILATION_FILES "${CMAKE_CURRENT_LIST_DIR}/src/misc/mmiocc.cc" "${CMAKE_CURRENT_LIST_DIR}/src/misc/mmio.c" "${CMAKE_CURRENT_LIST_DIR}/src/misc/misc.c") foreach(file ${BARTSUPPORT_PYTHON_SEPARATE_COMPILATION_FILES}) list(REMOVE_ITEM bart_support_SRCS "${file}") endforeach() if(NOT BART_ENABLE_MEM_CFL) list(REMOVE_ITEM BARTSUPPORT_PYTHON_SEPARATE_COMPILATION_FILES "${CMAKE_CURRENT_LIST_DIR}/src/misc/mmiocc.cc") endif() # ------------------------------------------------------------------------------ if(BART_DISABLE_PNG) list(REMOVE_ITEM bart_support_SRCS "${CMAKE_CURRENT_LIST_DIR}/src/misc/png.c") endif() set(LOG_BACKEND_SRCS "") list(REMOVE_ITEM bart_support_SRCS "${CMAKE_CURRENT_LIST_DIR}/src/misc/UTrace.cc") list(REMOVE_ITEM bart_support_SRCS "${CMAKE_CURRENT_LIST_DIR}/src/misc/Orchestra.cc") if(BART_LOG_BACKEND) set(DEBUG_C_FILE "${CMAKE_CURRENT_LIST_DIR}/src/misc/debug.c") set(LOG_BACKEND_SRCS "${DEBUG_C_FILE}") if(BART_LOG_SIEMENS_BACKEND) if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/src/misc/UTrace.cc") set(_ERR "Could not find the src/misc/UTrace.cc file\n") set(_ERR "${_ERR}You can download a copy of UTrace.cc at:\n") set(_ERR "${_ERR}https://www.mr-idea.com/communities/idea/Lists/Customer/UTrace.cc\n") message(FATAL_ERROR "${_ERR}") endif() # No need to add any include paths as the required code was copied into UTrace.cc from Siemens' IDEA framework list(APPEND LOG_BACKEND_SRCS "${CMAKE_CURRENT_LIST_DIR}/src/misc/UTrace.cc") endif() # ------------------------------------ if(BART_LOG_ORCHESTRA_BACKEND) set(OX_INSTALL_DIRECTORY "" CACHE PATH "Install directory of the GE Orchestra SDK") set(TOPDIR "${OX_INSTALL_DIRECTORY}/include") # Include recon libraries exported from the SDK CMake build set(RECON_LIBRARIES_INCLUDE_FILE ${OX_INSTALL_DIRECTORY}/lib/ReconLibraries.cmake) if(EXISTS ${RECON_LIBRARIES_INCLUDE_FILE}) include (${RECON_LIBRARIES_INCLUDE_FILE}) else(EXISTS ${RECON_LIBRARIES_INCLUDE_FILE}) message("Could not find ${RECON_LIBRARIES_INCLUDE_FILE}") message(FATAL_ERROR "Verify that the CMake OX_INSTALL_DIRECTORY option is set correctly") endif() # Include Orchestra SDK build configuration include (${TOPDIR}/recon/SDK/product.cmake) list(APPEND LOG_BACKEND_SRCS "${CMAKE_CURRENT_LIST_DIR}/src/misc/Orchestra.cc") endif() # ------------------------------------ if(BART_LOG_GADGETRON_BACKEND) # Actually we do nothing here, Gagdetron will provide the vendor_log function endif() endif() foreach(file ${LOG_BACKEND_SRCS}) list(REMOVE_ITEM bart_support_SRCS "${file}") endforeach() if(USE_CUDA) if("${CMAKE_VERSION}" VERSION_LESS 3.10) cuda_wrap_srcs(bartsupport_objs OBJ bartsupport_cuda_objs ${bart_support_CUSRCS}) else() set(bartsupport_cuda_objs ${bart_support_CUSRCS}) endif() endif() bart_add_object_library(bartsupport_objs ${bart_support_SRCS}) bart_add_library(bartsupport STATIC $ ${DEBUG_C_FILE} ${BARTSUPPORT_PYTHON_SEPARATE_COMPILATION_FILES} ${bartsupport_cuda_objs}) target_link_libraries(bartsupport PUBLIC ${LINALG_VENDOR_LIB} ${PNG_TGT} ${FFTW_TGT} ${OpenMP_TGT}) if(BART_LOG_BACKEND) if(BART_LOG_ORCHESTRA_BACKEND) # FIXME: need to check which libraries are actually required target_link_libraries(bartsupport PUBLIC "Core;Common;Control;System;${OX_3P_LIBS};${OX_OS_LIBS}") endif() endif() if(BART_ISMRMRD) target_link_libraries(bartsupport PUBLIC ${ISMRMRD_LIBRARIES}) endif() set_target_properties(bartsupport PROPERTIES EXPORT_NAME BARTSUPPORT INTERFACE_INCLUDE_DIRECTORIES $) ## Generate combined programs #============================================== set(MAIN_LIST) foreach(prog ${ALLPROGS}) set(MAIN_LIST "${MAIN_LIST} ${prog},") endforeach() set(MAIN_LIST "${MAIN_LIST} ()") string(STRIP ${MAIN_LIST} MAIN_LIST) #============================================== set(ALL_BART_SRCS "") foreach(curr_prog ${ALLPROGS}) configure_file_add_header("${CMAKE_CURRENT_LIST_DIR}/src/${curr_prog}.c" "/* Generated by cmake */;#include \"main.h\"") list(APPEND ALL_BART_SRCS ${OUTFILE}) endforeach() list(APPEND ALL_BART_SRCS "${CMAKE_CURRENT_LIST_DIR}/src/bart.c") bart_add_executable(bart ${ALL_BART_SRCS} ${LOG_BACKEND_SRCS}) target_compile_definitions(bart PRIVATE -DMAIN_LIST=${MAIN_LIST} -Dmain_bart=main) target_link_libraries(bart PRIVATE bartsupport) set_target_properties(bart PROPERTIES EXPORT_NAME BART) # ============================================================================== bart_add_object_library(bartmain_objs ${ALL_BART_SRCS}) bart_add_library(bartmain STATIC $ $ ${LOG_BACKEND_SRCS} ${BARTSUPPORT_PYTHON_SEPARATE_COMPILATION_FILES} ${bartsupport_cuda_objs}) target_compile_definitions(bartmain_objs PRIVATE -DMAIN_LIST=${MAIN_LIST}) target_link_libraries(bartmain PUBLIC ${LINALG_VENDOR_LIB} ${PNG_TGT} ${FFTW_TGT} ${OpenMP_TGT} ) if(BART_ISMRMRD) target_link_libraries(bartmain PUBLIC ${ISMRMRD_LIBRARIES}) endif() set_target_properties(bartmain PROPERTIES EXPORT_NAME BARTMAIN INTERFACE_INCLUDE_DIRECTORIES $) if(BART_ENABLE_MEM_CFL) set_target_properties(bartmain PROPERTIES LINKER_LANGUAGE CXX) endif() if(BART_LOG_BACKEND) # ensure that src/misc/misc.c will be compiled with logging backend support # but *ONLY* for the bartmain target target_compile_definitions(bartmain PRIVATE -DUSE_LOG_BACKEND) endif() # ============================================================================== if(BART_CREATE_PYTHON_MODULE) include(${CMAKE_CURRENT_LIST_DIR}/cmake/bart_python.cmake) configure_file(${CMAKE_CURRENT_LIST_DIR}/src/python/pyBART.cpp.in ${PROJECT_BINARY_DIR}/pyBART.cpp @ONLY) bart_add_library(pyBART SHARED ${PROJECT_BINARY_DIR}/pyBART.cpp ${BARTSUPPORT_PYTHON_SEPARATE_COMPILATION_FILES} $ $) if(CMAKE_VERSION VERSION_LESS 3.1) target_include_directories(pyBART PRIVATE ${Python_INCLUDE_DIR}) endif() target_compile_definitions(pyBART PRIVATE -DBART_WITH_PYTHON) target_link_libraries(pyBART PUBLIC "${Python_TGT};${PNG_TGT};${FFTW_TGT};${LINALG_VENDOR_LIB}") if(BART_ISMRMRD) target_link_libraries(pyBART PUBLIC ${ISMRMRD_LIBRARIES}) endif() if(APPLE) set_target_properties(pyBART PROPERTIES SUFFIX ".so") endif() set_target_properties(pyBART PROPERTIES PREFIX "" DEBUG_POSTFIX "" EXPORT_NAME pyBART) set(BART_pyBART_TGT pyBART) endif() #============================================== # TODO: Matlab code if(BART_MATLAB) find_package(Matlab REQUIRED) if(MATLAB_FOUND) message(STATUS "MATLAB LIBRARIES FOUND: ${MATLAB_LIBRARIES_DIR}") include_directories(${MATLAB_INCLUDE_DIR}) bart_add_executable(mat2cfl ${CMAKE_CURRENT_LIST_DIR}/src/mat2cfl.c ${LOG_BACKEND_SRCS}) target_link_libraries(mat2cfl PRIVATE bartsupport ${MATLAB_MAT_LIBRARY} ${MATLAB_ENG_LIBRARY} ${MATLAB_MX_LIBRARY}) set(BART_MATLAB_TGT mat2cfl) endif() endif() #============================================== # Testing code include(CTest) enable_testing() if(BUILD_TESTING) file(GLOB utests_list_SRCS "${CMAKE_CURRENT_LIST_DIR}/utests/test_*.c") foreach(f ${utests_list_SRCS}) file(STRINGS ${f} ut_register_lines REGEX "UT_REGISTER_TEST\\(.*\\)") string(REGEX REPLACE "UT_REGISTER_TEST\\(([a-zA-Z0-9_ ]+)\\)[\\r\\n\\t ]*\\;" "\\1" tests_list "${ut_register_lines}") get_filename_component(test_name ${f} NAME_WE) set(${test_name}_tests "") foreach(sub_test_name ${tests_list}) set(${test_name}_tests "${${test_name}_tests}call_${sub_test_name},") endforeach() add_executable(${test_name} ${CMAKE_CURRENT_LIST_DIR}/utests/utest.c ${f}) target_link_libraries(${test_name} PUBLIC bartsupport) target_compile_definitions(${test_name} PUBLIC UTESTS=${${test_name}_tests}) add_test(NAME ${test_name} COMMAND ${test_name}) endforeach() endif() # ------------------------------------------------------------------------------ ##Testing broke in 2c8c1a27 when adding a test. ## Include integration testing #if(NOT BART_MEMONLY_CFL) # add_subdirectory(tests) #endif() # ============================================================================== include(${CMAKE_CURRENT_LIST_DIR}/cmake/bart_install.cmake) # Packaging stuff (deb, rpm, windows installer) include(${CMAKE_CURRENT_LIST_DIR}/packaging/CPackConfig.cmake) # ============================================================================== add_custom_target(doxygen COMMAND ${CMAKE_CURRENT_LIST_DIR}/makedoc.sh WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} DEPENDS bart SOURCES makedoc.sh doxyconfig) add_custom_target(bart.syms COMMAND ${CMAKE_CURRENT_LIST_DIR}/rules/make_symbol_table.sh $ ${CMAKE_CURRENT_BINARY_DIR}/bart.syms WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS bart SOURCES makedoc.sh doxyconfig) if(BART_GENERATE_DOC) add_custom_command(TARGET bart POST_BUILD COMMAND ${CMAKE_CURRENT_LIST_DIR}/rules/update_commands.sh $ ${CMAKE_CURRENT_LIST_DIR}/doc/commands.txt ${ALLPROGS} ) endif() bart-0.5.00/LICENSE000066400000000000000000000031461353046746100135460ustar00rootroot00000000000000Copyright (c) 2013-2018. The Regents of the University of California. Copyright (c) 2013-2019. BART Developer Team and Contributors. Copyright (c) 2012. Intel Corporation. (src/lapacke/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bart-0.5.00/Makefile000066400000000000000000000267301353046746100142050ustar00rootroot00000000000000# Copyright 2013-2015. The Regents of the University of California. # Copyright 2015-2019. Martin Uecker # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # we have a two stage Makefile MAKESTAGE ?= 1 # silent make #MAKEFLAGS += --silent # auto clean on makefile updates AUTOCLEAN?=1 # clear out all implicit rules and variables MAKEFLAGS += -R # use for parallel make AR=./ar_lock.sh MKL?=0 CUDA?=0 ACML?=0 OMP?=1 SLINK?=0 DEBUG?=0 FFTWTHREADS?=1 ISMRMRD?=0 NOEXEC_STACK?=0 LOG_BACKEND?=0 LOG_SIEMENS_BACKEND?=0 LOG_ORCHESTRA_BACKEND?=0 LOG_GADGETRON_BACKEND?=0 ENABLE_MEM_CFL?=0 MEMONLY_CFL?=0 DESTDIR ?= / PREFIX ?= usr/local/ BUILDTYPE = Linux UNAME = $(shell uname -s) NNAME = $(shell uname -n) MYLINK=ln ifeq ($(UNAME),Darwin) BUILDTYPE = MacOSX MYLINK = ln -s endif ifeq ($(BUILDTYPE), MacOSX) MACPORTS ?= 1 endif ifeq ($(BUILDTYPE), Linux) # as the defaults changed on most Linux distributions # explicitly specify non-deterministic archives to not break make ARFLAGS ?= rsU else ARFLAGS ?= rs endif ifeq ($(UNAME),Cygwin) BUILDTYPE = Cygwin NOLAPACKE ?= 1 endif ifeq ($(UNAME),CYGWIN_NT-10.0) BUILDTYPE = Cygwin NOLAPACKE ?= 1 endif # Paths here = $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) root := $(here) srcdir = $(root)/src libdir = $(root)/lib bindir = $(root)/bin export TOOLBOX_PATH=$(root) # Automatic dependency generation DEPFILE = $(*D)/.$(*F).d DEPFLAG = -MMD -MF $(DEPFILE) ALLDEPS = $(shell find $(srcdir) utests -name ".*.d") # Compilation flags OPT = -O3 -ffast-math CPPFLAGS ?= -Wall -Wextra CFLAGS ?= $(OPT) -Wmissing-prototypes CXXFLAGS ?= $(OPT) ifeq ($(BUILDTYPE), MacOSX) CC ?= gcc-mp-6 else CC ?= gcc # for symbols in backtraces LDFLAGS += -rdynamic endif # openblas ifneq ($(BUILDTYPE), MacOSX) BLAS_BASE ?= /usr/ else ifeq ($(MACPORTS),1) BLAS_BASE ?= /opt/local/ CPPFLAGS += -DUSE_MACPORTS endif BLAS_BASE ?= /usr/local/opt/openblas/ endif # cuda CUDA_BASE ?= /usr/local/ # acml ACML_BASE ?= /usr/local/acml/acml4.4.0/gfortran64_mp/ # mkl MKL_BASE ?= /opt/intel/mkl/lib/intel64/ # fftw ifneq ($(BUILDTYPE), MacOSX) FFTW_BASE ?= /usr/ else FFTW_BASE ?= /opt/local/ endif # Matlab MATLAB_BASE ?= /usr/local/matlab/ # ISMRM ISMRM_BASE ?= /usr/local/ismrmrd/ # Main build targets are defined in build_targets.mk so that both CMake and Make can use the same definitions # set values for TBASE TFLP TNUM TRECO TCALIB TMRI TSIM TIO in build_targets.mk include build_targets.mk MODULES = -lnum -lmisc -lnum -lmisc MODULES_pics = -lgrecon -lsense -liter -llinops -lwavelet -llowrank -lnoncart MODULES_sqpics = -lsense -liter -llinops -lwavelet -llowrank -lnoncart MODULES_pocsense = -lsense -liter -llinops -lwavelet MODULES_nlinv = -lnoir -liter -lnlops -llinops MODULES_moba = -lmoba -lnoir -liter -lnlops -llinops -lwavelet MODULES_bpsense = -lsense -lnoncart -liter -llinops -lwavelet MODULES_itsense = -liter -llinops MODULES_ecalib = -lcalib MODULES_ecaltwo = -lcalib MODULES_caldir = -lcalib MODULES_walsh = -lcalib MODULES_calmat = -lcalib MODULES_cc = -lcalib MODULES_ccapply = -lcalib MODULES_estvar = -lcalib MODULES_nufft = -lnoncart -liter -llinops MODULES_rof = -liter -llinops MODULES_tgv = -liter -llinops MODULES_bench = -lwavelet -llinops MODULES_phantom = -lsimu MODULES_bart = -lbox -lgrecon -lsense -lnoir -liter -llinops -lwavelet -llowrank -lnoncart -lcalib -lsimu -lsake -ldfwavelet -lnlops -lmoba MODULES_sake = -lsake MODULES_traj = -lnoncart MODULES_wave = -liter -lwavelet -llinops -llowrank MODULES_threshold = -llowrank -liter -ldfwavelet -llinops -lwavelet MODULES_fakeksp = -lsense -llinops MODULES_lrmatrix = -llowrank -liter -llinops MODULES_estdims = -lnoncart -llinops MODULES_ismrmrd = -lismrm MODULES_wavelet = -llinops -lwavelet MODULES_wshfl = -llinops -lwavelet -liter -llowrank MAKEFILES = $(wildcard $(root)/Makefiles/Makefile.*) ALLMAKEFILES = $(root)/Makefile $(wildcard $(root)/Makefile.* $(root)/*.mk $(root)/rules/*.mk $(root)/Makefiles/Makefile.*) -include Makefile.$(NNAME) -include Makefile.local -include $(MAKEFILES) # clang ifeq ($(findstring clang,$(CC)),clang) CFLAGS += -fblocks LDFLAGS += -lBlocksRuntime endif CXX ?= g++ LINKER ?= $(CC) ifeq ($(ISMRMRD),1) TMRI += ismrmrd MODULES_bart += -lismrm endif ifeq ($(NOLAPACKE),1) CPPFLAGS += -DNOLAPACKE MODULES += -llapacke endif XTARGETS += $(TBASE) $(TFLP) $(TNUM) $(TIO) $(TRECO) $(TCALIB) $(TMRI) $(TSIM) TARGETS = bart $(XTARGETS) ifeq ($(DEBUG),1) CPPFLAGS += -g CFLAGS += -g endif ifeq ($(NOEXEC_STACK),1) CPPFLAGS += -DNOEXEC_STACK endif ifeq ($(PARALLEL),1) MAKEFLAGS += -j endif ifeq ($(MAKESTAGE),1) .PHONY: doc/commands.txt $(TARGETS) default all clean allclean distclean doc/commands.txt doxygen test utest gputest $(TARGETS): make MAKESTAGE=2 $(MAKECMDGOALS) tests/test-%: force make MAKESTAGE=2 $(MAKECMDGOALS) force: ; else CPPFLAGS += $(DEPFLAG) -iquote $(srcdir)/ CFLAGS += -std=gnu11 CXXFLAGS += -std=c++11 default: bart doc/commands.txt .gitignore -include $(ALLDEPS) # cuda NVCC = $(CUDA_BASE)/bin/nvcc ifeq ($(CUDA),1) CUDA_H := -I$(CUDA_BASE)/include CPPFLAGS += -DUSE_CUDA $(CUDA_H) ifeq ($(BUILDTYPE), MacOSX) CUDA_L := -L$(CUDA_BASE)/lib -lcufft -lcudart -lcublas -m64 -lstdc++ else CUDA_L := -L$(CUDA_BASE)/lib64 -lcufft -lcudart -lcublas -lstdc++ -Wl,-rpath $(CUDA_BASE)/lib64 endif else CUDA_H := CUDA_L := endif # sm_20 no longer supported in CUDA 9 GPUARCH_FLAGS ?= NVCCFLAGS = -DUSE_CUDA -Xcompiler -fPIC -Xcompiler -fopenmp -O3 $(GPUARCH_FLAGS) -I$(srcdir)/ -m64 -ccbin $(CC) #NVCCFLAGS = -Xcompiler -fPIC -Xcompiler -fopenmp -O3 -I$(srcdir)/ %.o: %.cu $(NVCC) $(NVCCFLAGS) -c $^ -o $@ $(NVCC) $(NVCCFLAGS) -M $^ -o $(DEPFILE) # OpenMP ifeq ($(OMP),1) CFLAGS += -fopenmp CXXFLAGS += -fopenmp else CFLAGS += -Wno-unknown-pragmas CXXFLAGS += -Wno-unknown-pragmas endif # BLAS/LAPACK ifeq ($(ACML),1) BLAS_H := -I$(ACML_BASE)/include BLAS_L := -L$(ACML_BASE)/lib -lgfortran -lacml_mp -Wl,-rpath $(ACML_BASE)/lib CPPFLAGS += -DUSE_ACML else BLAS_H := -I$(BLAS_BASE)/include ifeq ($(BUILDTYPE), MacOSX) BLAS_L := -L$(BLAS_BASE)/lib -lopenblas else ifeq ($(NOLAPACKE),1) BLAS_L := -L$(BLAS_BASE)/lib -llapack -lblas CPPFLAGS += -Isrc/lapacke else BLAS_L := -L$(BLAS_BASE)/lib -llapacke -lblas endif endif endif ifeq ($(MKL),1) BLAS_H := -I$(MKL_BASE)/include BLAS_L := -L$(MKL_BASE)/lib/intel64 -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core CPPFLAGS += -DUSE_MKL -DMKL_Complex8="complex float" -DMKL_Complex16="complex double" CFLAGS += -DUSE_MKL -DMKL_Complex8="complex float" -DMKL_Complex16="complex double" endif CPPFLAGS += $(FFTW_H) $(BLAS_H) # png PNG_L := -lpng ifeq ($(SLINK),1) PNG_L += -lz endif ifeq ($(LINKER),icc) PNG_L += -lz endif # fftw FFTW_H := -I$(FFTW_BASE)/include/ FFTW_L := -L$(FFTW_BASE)/lib -lfftw3f ifeq ($(FFTWTHREADS),1) FFTW_L += -lfftw3f_threads CPPFLAGS += -DFFTWTHREADS endif # Matlab MATLAB_H := -I$(MATLAB_BASE)/extern/include MATLAB_L := -Wl,-rpath $(MATLAB_BASE)/bin/glnxa64 -L$(MATLAB_BASE)/bin/glnxa64 -lmat -lmx -lm -lstdc++ # ISMRM ifeq ($(ISMRMRD),1) ISMRM_H := -I$(ISMRM_BASE)/include ISMRM_L := -L$(ISMRM_BASE)/lib -lismrmrd else ISMRM_H := ISMRM_L := endif # Enable in-memory CFL files ifeq ($(ENABLE_MEM_CFL),1) CPPFLAGS += -DUSE_MEM_CFL miscextracxxsrcs += $(srcdir)/misc/mmiocc.cc LDFLAGS += -lstdc++ endif # Only allow in-memory CFL files (ie. disable support for all other files) ifeq ($(MEMONLY_CFL),1) CPPFLAGS += -DMEMONLY_CFL miscextracxxsrcs += $(srcdir)/misc/mmiocc.cc LDFLAGS += -lstdc++ endif # Logging backends ifeq ($(LOG_BACKEND),1) CPPFLAGS += -DUSE_LOG_BACKEND ifeq ($(LOG_SIEMENS_BACKEND),1) miscextracxxsrcs += $(srcdir)/misc/UTrace.cc endif ifeq ($(LOG_ORCHESTRA_BACKEND),1) miscextracxxsrcs += $(srcdir)/misc/Orchestra.cc endif endif # change for static linking ifeq ($(SLINK),1) # work around fortran problems with static linking LDFLAGS += -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -Wl,--allow-multiple-definition LIBS += -lmvec BLAS_L += -llapack -lblas -lgfortran -lquadmath endif # Modules .LIBPATTERNS := lib%.a vpath %.a lib DIRS = $(root)/rules/*.mk include $(DIRS) # sort BTARGETS after everything is included BTARGETS:=$(sort $(BTARGETS)) XTARGETS:=$(sort $(XTARGETS)) .gitignore: .gitignore.main Makefile* @echo '# AUTOGENERATED. DO NOT EDIT. (are you looking for .gitignore.main ?)' > .gitignore cat .gitignore.main >> .gitignore @echo $(patsubst %, /%, $(TARGETS) $(UTARGETS)) | tr ' ' '\n' >> .gitignore doc/commands.txt: bart ./rules/update_commands.sh ./bart doc/commands.txt $(XTARGETS) doxygen: makedoc.sh doxyconfig bart ./makedoc.sh all: .gitignore $(TARGETS) # special targets $(XTARGETS): CPPFLAGS += -DMAIN_LIST="$(XTARGETS:%=%,) ()" -include src/main.h bart: CPPFLAGS += -DMAIN_LIST="$(XTARGETS:%=%,) ()" -include src/main.h mat2cfl: $(srcdir)/mat2cfl.c -lnum -lmisc $(CC) $(CFLAGS) $(MATLAB_H) -omat2cfl $+ $(MATLAB_L) $(CUDA_L) # implicit rules %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< %.o: %.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< ifeq ($(PARALLEL),1) (%): % $(AR) $(ARFLAGS) $@ $% else (%): % $(AR) $(ARFLAGS) $@ $% rm $% endif # we add the rm because intermediate files are not deleted # automatically for some reason # (but it produces errors for parallel builds for make all) .SECONDEXPANSION: $(TARGETS): % : src/main.c $(srcdir)/%.o $$(MODULES_%) $(MODULES) $(LINKER) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -Dmain_real=main_$@ -o $@ $+ $(FFTW_L) $(CUDA_L) $(BLAS_L) $(PNG_L) $(ISMRM_L) $(LIBS) -lm # rm $(srcdir)/$@.o UTESTS=$(shell $(root)/utests/utests-collect.sh ./utests/$@.c) .SECONDEXPANSION: $(UTARGETS): % : utests/utest.c utests/%.o $$(MODULES_%) $(MODULES) $(CC) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -DUTESTS="$(UTESTS)" -o $@ $+ $(FFTW_L) $(CUDA_L) $(BLAS_L) $(LIBS) -lm # linker script version - does not work on MacOS X # $(CC) $(LDFLAGS) -Wl,-Tutests/utests.ld $(CFLAGS) -o $@ $+ $(FFTW_L) $(CUDA_L) $(BLAS_L) -lm clean: rm -f `find $(srcdir) -name "*.o"` rm -f $(root)/utests/*.o rm -f $(patsubst %, %, $(UTARGETS)) rm -f $(libdir)/.*.lock allclean: clean rm -f $(libdir)/*.a $(ALLDEPS) rm -f $(patsubst %, %, $(TARGETS)) rm -f $(srcdir)/misc/version.inc rm -rf $(root)/tests/tmp/*/ rm -rf $(root)/doc/dx rm -f $(root)/doc/commands.txt touch isclean distclean: allclean -include isclean isclean: $(ALLMAKEFILES) ifeq ($(AUTOCLEAN),1) @echo "CONFIGURATION MODIFIED. RUNNING FULL REBUILD." touch isclean make allclean || rm isclean else ifneq ($(MAKECMDGOALS),allclean) @echo "CONFIGURATION MODIFIED." endif endif # automatic tests # system tests TOOLDIR=$(root) TESTS_TMP=$(root)/tests/tmp/$$$$/ TESTS_OUT=$(root)/tests/out/ include $(root)/tests/*.mk test: ${TESTS} gputest: ${TESTS_GPU} pythontest: ${TESTS_PYTHON} # unit tests # define space to faciliate running executables define \n endef utests-all: $(UTARGETS) $(patsubst %,$(\n)./%,$(UTARGETS)) utest: utests-all @echo ALL UNIT TESTS PASSED. endif # MAKESTAGE install: bart $(root)/doc/commands.txt install -d $(DESTDIR)/$(PREFIX)/bin/ install bart $(DESTDIR)/$(PREFIX)/bin/ install -d $(DESTDIR)/$(PREFIX)/share/doc/bart/ install $(root)/doc/*.txt $(root)/README $(DESTDIR)/$(PREFIX)/share/doc/bart/ install -d $(DESTDIR)/$(PREFIX)/lib/bart/commands/ # generate release tar balls (identical to github) %.tar.gz: git archive --prefix=bart-$(patsubst bart-%.tar.gz,%,$@)/ -o $@ v$(patsubst bart-%.tar.gz,%,$@) # symbol table bart.syms: bart rules/make_symbol_table.sh bart bart.syms bart-0.5.00/Makefiles/000077500000000000000000000000001353046746100144355ustar00rootroot00000000000000bart-0.5.00/Makefiles/README.md000066400000000000000000000017261353046746100157220ustar00rootroot00000000000000### Custom Makefiles Put custom Makefiles here, to be included in the standard Makefile. The build will automatically include the following files in this directory matching the expansion `Makefiles.*` Example custom Makefile for modifying build: ```bash ## Makefile.local # Makefile for my local build DEBUG = 1 # Parallel make PARALLEL ?= 1 # GPU CUDA=0 CC=clang OMP=0 # Paths FFTW_BASE := /opt/local/ MATLAB_BASE := /Applications/MATLAB_R2016a.app CUDA_BASE = /usr/local/cuda/ BLAS_BASE := /opt/local ``` Example Makefile and library rules for adding a custom program: ```bash ## Makefiles/Makefile.sum # Compile my custom program, src/sum.c, which relies on # my custom library, lib/libsum.a MODULES_sum = -lsum MODULES_bart += -lsum XTARGETS += sum ``` ```bash ### rules/sum.mk # Build my custom library with files under src/sum/ sumsrcs := $(wildcard $(srcdir)/sum/*.c) sumobjs := $(sumsrcs:.c=.o) .INTERMEDIATE: $(sumobjs) lib/libsum.a: libsum.a($(sumobjs)) ``` bart-0.5.00/README000066400000000000000000000273471353046746100134320ustar00rootroot00000000000000 0. License ========== See LICENSE file for licensing information. ------------------------------------------------------------------------------- The tools in this software implement various reconstruction algorithms for Magnetic Resonance Imaging. The software is intended for research use only and NOT FOR DIAGNOSTIC USE. It comes without any warranty (see LICENSE for details). Please cite the corresponding articles when using these tools. Some references can be found at the end of this file. The source code might provide more detailed references, e.g. for specific iterative algorithms. 1. Help ======= Please direct all questions or comments to the public mailing list: mrirecon@lists.eecs.berkeley.edu https://lists.eecs.berkeley.edu/sympa/info/mrirecon Note: This list has a public archive! Please do not send any confidential information. Updates and further information can be found here: http://mrirecon.github.io/bart/ 2. Installation =============== 2.1. Prerequisites ------------------ GCC compiler, the FFTW library, and optionally CUDA. (see recon/Makefile to turn options on or off) The minimum GCC supported is 5.0. It should also be possible to use the clang compiler, but older version before version 4.0 are known to cause problems. The software can be used in combination with Matlab or octave. There is limited support for reading Cartesian data encoded with the ISMRM Raw Data format when linking with the ISMRMRD library (http://ismrmrd.sourceforge.net/). In the following, the symbol '`$`' indicates a shell prompt. Do not type '`$`' when entering commands. ### 2.1.1. Linux The software tools in recon should run on any recent Linux distribution. To install the required libraries on Debian and Ubuntu run: $ sudo apt-get install gcc make libfftw3-dev liblapacke-dev libpng-dev libopenblas-dev gfortran (optional) $ sudo apt-get install octave (optional) install version 0.5.2 of the ISMRMRD library ### 2.1.2. Mac OS X Xcode is required and it is recommended to install a newer version of gcc from MacPorts (http://www.macports.org/). $ sudo port install fftw-3-single $ sudo port install gcc6 $ sudo port install libpng $ sudo port install openblas (optional) $ sudo port install octave (optional) install version 0.5.2 of the ISMRMRD library ### 2.1.3. Windows Note that Windows is currently not supported. Nevertheless, many people use BART on Windows. If you have trouble to get it to work, you may want to try an older version (e.g. version 4.00). The recommended way to use BART on Windows is with the Windows Subsystem for Linux (WSL) which is available for Windows 10. If you use WSL, you need to either use the clang compiler or gcc with the NOEXEC_STACK option. BART should also work with Cygwin: https://www.cygwin.com/ Install Cygwin and select the following packages: Devel: gcc, make Math: fftw3, fftw3-doc, libfftw3-devel, libfftw3_3 Math: liblapack-devel, liblapack-doc, liblapack0 Libs: libpng, libpng-devel Then use the cygwin shell to compile BART as described below. An alternative to using the Windows Subsystem for Linux or Cygwin is a virtual machine with Linux installed. 2.2. Downloading and Compilation -------------------------------- If you are a git user, you can simply clone our public repository: $ git clone https://github.com/mrirecon/bart Otherwise, please download the latest version as a zip file from Github: http://github.com/mrirecon/bart/releases/latest and unpack it somewhere on your computer. Open a terminal window and enter the bart directory (the top-level directory with the Makefile in it). To build the reconstruction tools type: $ make If you have installed the ISMRMRD library version 0.5.2, you can also build the ISMRM raw data import tool: $ make ismrmrd 2.3. Getting Started -------------------- ### 2.3.1. Organization . main directory / built software tools Makefile Makefile matlab/ Matlab helper scripts python/ Python helper functions doc/ documentation rules/ more built-related files scripts/ various helper scripts and examples src/ source code src/calib source code for sensitivity calibration src/sense source code for SENSE or ESPIRiT reconstruction src/noir source code for nonlinear inversion src/sake source code for SAKE reconstruction src/wavelet source code for wavelets src/num base library with numerical functions src/iter iterative algorithms src/linops library of linear operators src/nlops library of nonlinear operators src/misc miscellaneous (e.g. I/O) src/ismrm support for ISMRM raw data format src/simu source code for simulation src/noncart source code for non-uniform FFT tests/ system tests utests/ unit tests lib/ built software libraries ### 2.3.2. Terminal When using the toolbox commands from a UNIX shell, it is recommended to set the TOOLBOX_PATH to the base directory and to add it to the PATH variable. You can do this by running the following command: $ . startup.sh Note: The dot or 'source' command is needed so that the variables are imported into the current shell. ### 2.3.3. Matlab You can set the TOOLBOX_PATH to the base directory and to add it to the Matlab path by running the following command in the bart directory: >> startup (Note: The '>>' indicates the shell prompt. Do not type '>>' when entering commands.) You can use Matlab to read and visualize/process files. To write a data file 'xyz' from Matlab you can run: >> writecfl('xyz', A); Note, that the name 'xyz' is used without filename extension. See below for more information about the file format used in BART. To read the data file 'xyz' back into Matlab use: >> A = readcfl('xyz'); To call a BART tool (e.g. ecalib) from Matlab, you can use the 'bart' command: >> sensitivities = bart('ecalib', kspace); Download and unpack the examples which demonstrate interoperability with Matlab. Go to the examples directory and run: >> examples ### 2.3.4. Python You can set the TOOLBOX_PATH to the base directory and start a Python interactively as follows: $ python -i startup.py To avoid doing the above everytime, it is recommended to update your PYTHONPATH environment. For example, in Linux, assuming your TOOLBOX_PATH is set, add the below line to your bashrc file. $ export PYTHONPATH="${TOOLBOX_PATH}/python:$PYTHONPATH" After doing so, we can simply import as needed. >>> from bart import bart >>> import cfl You can use Python to read and visualize/process files. To write a data file 'xyz' from Python you can run: >>> cfl.writecfl('xyz', A); Note, that the name 'xyz' is used without filename extension. See below for more information about the file format used in BART. To read the data file 'xyz' back into Python use: >>> A = cfl.readcfl('xyz'); To call a BART tool (e.g. ecalib) from Python, you can use the 'bart' command: >>> sensitivities = bart(1, 'ecalib', kspace); The bart function expects the following signature: >>> = bart(, , , ...) To use BART in a script, please follow the steps in the startup.py file. 3. Data Format ============== 3.1. Generic ------------ The input and output datasets are each stored in a pair of files: one header (*.hdr) and one raw data (*.cfl). The header is a simple text readable file that describes the dimensions of the data. The raw data file is a binary file containing a single contiguous block of array data of dimensions described in the header stored in column-major order (first index is sequential). The raw data file is complex float (32 bit real + 32 bit imaginary, IEEE 747 binary32 little-endian). Convenience methods to read and write our data files using Matlab may be found in the matlab/ directory (readcfl.m and writecfl.m). Similar methods for Python may be found in the python/ directory (cfl.py). 3.2. Magnetic Resonance Imaging Data ------------------------------------ For MRI data and images, the dimensions are usually assigned in the following order: 0 readout 1 phase-encoding dimension 1 2 phase-encoding dimension 2 3 receive channels 4 ESPIRiT maps ... ... (more dimensions are defined in src/misc/mri.h) Undersampled data is stored with zeros in the unsampled positions. 3.3. Non-Cartesian Trajectories and Samples ------------------------------------------- The k-space coordinates for each sample are stored along dimension 0 which must have size equal to three. The unit of measurement is 1/FOV. Dimension 1 stores the samples along a single readout windows while dimension 2 may be used to differentiate between different lines (e.g. radial spokes). Channel (3) and map (4) dimensions must not be used (i.e. have size one), while other dimensions can be used as for Cartesian data. Non-Cartesian samples are stored in a similar way as trajectories except that dimension 0 is not used. The channel dimension can be used for different receiver coils as usual. 4. Command-line Tools ===================== All tools operate on the simple file format given above. Indices and dimensions run from 0 to N-1. Sometimes a set of dimensions is given as a bitmask where the lowest bit corresponds to the 0st dimension. For example, an inverse Fourier transform of first three dimensions can be performed with the following command: $ bart fft -i 7 kspace volume More information about each command can be found in 'doc/commands.txt'. 5. Information for Contributors =============================== Thank you for helping to improve BART! In order for us to be able to accept your contribution, it has to be released under the BSD license used by BART (see LICENSE file). By submitting patches to us it is understood that you agree to these terms and that you confirm that you hold all necessary rights yourself or have permission from the copyright holder. Please also add the name of the copyright holder and name and email of the author(s) to the copyright headers in all new or changed files. 6. Troubleshooting ================== 6.1. Installation Problems -------------------------- When problems occur after updating BART or changing build variables, it may help to clean the build environment and to recompile BART: $ make allclean $ make Make sure the PATH and TOOLBOX_PATH environment variables are set correctly. Sometimes, several versions of BART are installed and the wrong version is used accidentally. 6.2. Reporting Problems ----------------------- Please report problems to our mailing list and include the following information (as applicable): * The output of the 'version' command: $ bart version -V * The exact BART command-line that caused the problem. * The specific error message. * Information about the data files used when the problem occured (please provide atleast the dimensions of all input files). 6.3. Debugging -------------- See 'doc/debugging.txt' for details. 7. References ============= * Tamir JI, Ong F, Cheng JY, Uecker M, Lustig M, Generalized Magnetic Resonance Image Reconstruction using The Berkeley Advanced Reconstruction Toolbox, ISMRM Workshop on Data Sampling and Image Reconstruction, Sedona 2016 * Uecker M, Ong F, Tamir JI, Bahri D, Virtue P, Cheng JY, Zhang T, Lustig M, Berkeley Advanced Reconstruction Toolbox, Annual Meeting ISMRM, Toronto 2015 In: Proc Intl Soc Mag Reson Med 23:2486 * Uecker M, Virtue P, Ong F, Murphy MJ, Alley MT, Vasanawala SS, Lustig M, Software Toolbox and Programming Library for Compressed Sensing and Parallel Imaging, ISMRM Workshop on Data Sampling and Image Reconstruction, Sedona 2013 References related to implemented methods and algorithms can be found in the file 'doc/references.txt'. bart-0.5.00/README.md000066400000000000000000000023171353046746100140170ustar00rootroot00000000000000 BART: Toolbox for Computational Magnetic Resonance Imaging ========================================================== [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.592960.svg)](https://doi.org/10.5281/zenodo.592960) The Berkeley Advanced Reconstruction Toolbox (BART) is a free and open-source image-reconstruction framework for Computational Magnetic Resonance Imaging. The tools in this software implement various reconstruction algorithms for Magnetic Resonance Imaging. The software is intended for research use only and NOT FOR DIAGNOSTIC USE. It comes without any warranty (see LICENSE for details). For more information: https://mrirecon.github.io/bart/ Information for Contributors ---------------------------- Thank you for helping to improve BART! In order for us to be able to accept your contribution, it has to be released under the BSD license used by BART (see LICENSE file). By submitting patches to us it is understood that you agree to these terms and that you confirm that you hold all necessary rights yourself or have permission from the copyright holder. Please also add the name of the copyright holder and name and email of the author(s) to the copyright headers in all new or changed files. bart-0.5.00/ar_lock.sh000077500000000000000000000006411353046746100145070ustar00rootroot00000000000000#!/bin/bash set -e if command -v flock > /dev/null ; then flock `dirname $2`/.`basename $2`.lock -c "ar $*" exit 0 fi if command -v shlock > /dev/null ; then LOCK=/tmp/`basename $2`.lock trap 'rm -f ${LOCK} ; exit 1' 1 2 3 15 while true ; do if shlock -p $$ -f ${LOCK} ; then ar $* rm -rf ${LOCK} exit 0 else sleep 1 fi done fi echo "Error: no flock/shlock command!" exit 1 bart-0.5.00/build_targets.mk000066400000000000000000000012321353046746100157140ustar00rootroot00000000000000# Main build targets # TBASE=show slice crop resize join transpose squeeze flatten zeros ones flip circshift extract repmat bitmask reshape version delta copy casorati vec poly index TFLP=scale invert conj fmac saxpy sdot spow cpyphs creal carg normalize cdf97 pattern nrmse mip avg cabs zexp TNUM=fft fftmod fftshift noise bench threshold conv rss filter mandelbrot wavelet window var std fftrot TRECO=pics pocsense sqpics itsense nlinv moba nufft rof tgv sake wave lrmatrix estdims estshift estdelay wavepsf wshfl TCALIB=ecalib ecaltwo caldir walsh cc ccapply calmat svd estvar whiten TMRI=homodyne poisson twixread fakeksp looklocker TSIM=phantom traj TIO=toimg bart-0.5.00/cmake/000077500000000000000000000000001353046746100136155ustar00rootroot00000000000000bart-0.5.00/cmake/BARTConfig.cmake.in000066400000000000000000000060061353046746100171040ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen @PACKAGE_INIT@ set(BART_ENABLE_MEM_CFL @BART_ENABLE_MEM_CFL@) set(BART_FPIC @BART_FPIC@) set(BART_FFTWTHREADS @BART_FFTWTHREADS@) set(BART_DISABLE_PNG @BART_DISABLE_PNG@) set(BART_ISMRMRD @BART_ISMRMRD@) set(BART_LOCAL_FFTW @BART_LOCAL_FFTW@) set(BART_LOG_BACKEND @BART_LOG_BACKEND@) set(BART_LOG_SIEMENS_BACKEND @BART_LOG_SIEMENS_BACKEND@) set(BART_LOG_ORCHESTRA_BACKEND @BART_LOG_ORCHESTRA_BACKEND@) set(BART_LOG_GADGETRON_BACKEND @BART_LOG_GADGETRON_BACKEND@) set(BART_NO_LAPACKE @BART_NO_LAPACKE@) set(BART_MATLAB @BART_MATLAB@) set(BART_MEMONLY_CFL @BART_MEMONLY_CFL@) set(BART_USE_CUDA @USE_CUDA@) set(BART_USE_NATIVE_CUDA @BART_USE_NATIVE_CUDA@) set(BART_USE_OPENMP @USE_OPENMP@) set(BART_REDEFINE_PRINTF_FOR_TRACE @BART_REDEFINE_PRINTF_FOR_TRACE@) set(BART_LINALG_VENDOR "@LINALG_VENDOR@") set(LINALG_VENDOR "@LINALG_VENDOR@") # ------------------------------------------------------------------------------ get_filename_component(BART_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) list(INSERT CMAKE_MODULE_PATH 0 ${BART_CMAKE_DIR}) include(CMakeFindDependencyMacro) include(${BART_CMAKE_DIR}/BARTFindBLASlib.cmake) if(BART_ISMRMRD) find_dependency(ISMRMRD) endif() if(NOT BART_LOCAL_FFTW) if(CMAKE_VERSION VERSION_LESS 3.9) find_package(FFTW 3 REQUIRED COMPONENTS FFTWF FFTWF_MT) else() find_dependency(FFTW 3 COMPONENTS FFTWF FFTWF_MT) endif() else() find_dependency(Threads) endif() if(NOT BART_DISABLE_PNG) find_dependency(PNG) if(CMAKE_VERSION VERSION_LESS 3.5) add_library(PNG::PNG SHARED IMPORTED GLOBAL) set_target_properties(PNG::PNG PROPERTIES IMPORTED_LOCATION "${PNG_LIBRARY}" INTERFACE_DEFINITIONS "${PNG_DEFINITIONS}" INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${PNG_LIBRARIES}" ) endif() endif() if(BART_USE_OPENMP) if(CMAKE_VERSION VERSION_LESS 3.11) # Actually CMake 3.9 should be enough for OpenMP::OpenMP support, # however, until CMake 3.11 we might get problems with the # INTERFACE_COMPILE_OPTIONS property if we are compiling with # CMake's native CUDA compilation find_package(BOpenMP REQUIRED) # BOpenMP is FindOpenMP.cmake from 3.12 else() find_package(OpenMP REQUIRED) endif() endif() if(BART_USE_NATIVE_CUDA) find_dependency(CUDAlibs COMPONENTS CUBLAS CUFFT) endif() list(REMOVE_AT CMAKE_MODULE_PATH 0) # ============================================================================== set_and_check(BARTTargetForEmbedding "${BART_CMAKE_DIR}/BARTTargetsForEmbedding.cmake") include(${BARTTargetForEmbedding}) set(BARTTargetGeneral "${BART_CMAKE_DIR}/BARTTargets.cmake") if(NOT TARGET BART::BART AND EXISTS ${BARTTargetGeneral}) include(${BARTTargetGeneral}) endif() # ============================================================================== bart-0.5.00/cmake/BARTFindBLASlib.cmake000066400000000000000000000062741353046746100173120ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen macro(setup_linalg_vendor_on_success vendor target) if(${target}_FOUND) set(LINALG_VENDOR_LIB ${ARGN}) set(LINALG_VENDOR_FOUND TRUE) set(LINALG_VENDOR ${vendor} CACHE STRING "Vendor type for linear algebra library" FORCE) set(LINALG_VENDOR_TGT ${target}) endif() endmacro() ##============================================================== if(NOT "${LINALG_VENDOR}" STREQUAL "") # If the user specifies LINALG_VENDOR, make sure we find what he wants set(FIND_PACKAGE_ARG "REQUIRED") else() set(FIND_PACKAGE_ARG) endif() ## Switch based on the linear algebra optimized library to ## use. Note that the first library successfully found ## will be used ## ## -*-*- Try with only a BLAS library first if BART_NO_LAPACKE is set if(BART_NO_LAPACKE AND (NOT LINALG_VENDOR OR LINALG_VENDOR STREQUAL "BLAS")) find_package(LAPACKE ${FIND_PACKAGE_ARG} COMPONENTS lapack cblas blas) setup_linalg_vendor_on_success("BLAS" LAPACKE LAPACKE::LAPACK LAPACKE::CBLAS LAPACKE::BLAS) endif() ## -*-*- Try AMD BLIS/libFlame next if(NOT LINALG_VENDOR OR LINALG_VENDOR MATCHES "AMD_FLAME") find_package(libFlame ${FIND_PACKAGE_ARG}) setup_linalg_vendor_on_success("AMD_FLAME" libFlame libFlame::libFlame) if(libFlame_FOUND) if(NOT BART_NO_LAPACKE) find_package(LAPACKE REQUIRED COMPONENTS LAPACKE) get_target_property( libFlame_INTERFACE_LINK_LIBRARIES ${LINALG_VENDOR_LIB} INTERFACE_LINK_LIBRARIES) set_target_properties(${LINALG_VENDOR_LIB} PROPERTIES INTERFACE_LINK_LIBRARIES "${libFlame_INTERFACE_LINK_LIBRARIES};LAPACKE::LAPACKE") endif() endif() endif() ## -*-*- Try OpenBLAS next if(NOT LINALG_VENDOR OR LINALG_VENDOR MATCHES "OpenBLAS") find_package(OpenBLAS ${FIND_PACKAGE_ARG}) setup_linalg_vendor_on_success("OpenBLAS" OpenBLAS OpenBLAS::OpenBLAS) endif() ## ## -*-*- Try ATLAS version next if(NOT LINALG_VENDOR OR LINALG_VENDOR MATCHES "ATLAS") find_package(ATLAS ${FIND_PACKAGE_ARG}) setup_linalg_vendor_on_success("ATLAS" ATLAS ATLAS::ATLAS) endif() ## ## -*-*- Try Generic LAPACKE version Last if(NOT LINALG_VENDOR OR LINALG_VENDOR MATCHES "LAPACKE") #NOTE: By specifying Fortran here, linking to lapack becomes easier # See https://blog.kitware.com/fortran-for-cc-developers-made-easier-with-cmake/ if(NOT WIN32) enable_language(Fortran) endif() ## Only very new versions of LAPACK (> 3.5.0) have built in support ## for cblas and lapacke. This method is not very robust to older ## versions of lapack that might be able to be supported. ## It is know to work local builds find_package(LAPACKE ${FIND_PACKAGE_ARG}) setup_linalg_vendor_on_success("LAPACKE" LAPACKE LAPACKE::LAPACKE LAPACKE::LAPACKE LAPACKE::CBLAS LAPACKE::BLAS) endif() # Fix weird error when compiling on Mac... if(APPLE) include_directories(${${LINALG_VENDOR_TGT}_INCLUDE_DIRS}) endif() ## ## -*-*- Finally, set include_directories -*-*-* if(NOT LINALG_VENDOR_FOUND) message(FATAL_ERROR "No valid linear algebra libraries found!") endif() bart-0.5.00/cmake/FindATLAS.cmake000066400000000000000000000167641353046746100163020ustar00rootroot00000000000000#.rst: # FindATLAS # ------------- # # Find ATLAS include dirs and libraries # # Use this module by invoking find_package with the form:: # # find_package(ATLAS # [REQUIRED] # Fail with error if ATLAS is not found # ) # # [OPTIONAL] set(ATLAS_REQUIRE_THREADED [TRUE|FALSE]) to find threaded versions of the libraries # # This module defines:: # # ATLAS_FOUND - set to true if the library is found # ATLAS_INCLUDE_DIRS - list of required include directories # ATLAS_LIBRARIES - list of libraries to be linked # ATLAS_VERSION_MAJOR - major version number # ATLAS_VERSION_MINOR - minor version number # ATLAS_VERSION_PATCH - patch version number # ATLAS_VERSION_STRING - version number as a string (ex: "0.2.18") # # # This module reads hints about search locations from variables # (either CMake variables or environment variables):: # # ATLAS_ROOT - Preferred installation prefix for ATLAS # ATLAS_DIR - Preferred installation prefix for ATLAS # # # ATLAS::ATLAS - Imported target for the ATLAS library # # ============================================================================== # Copyright 2016 Hans J. Johnson # Copyright 2018 Damien Nguyen # # Distributed under the OSI-approved BSD License (the "License") # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ============================================================================== set(ATLAS_SEARCH_PATHS ${ATLAS_ROOT} $ENV{ATLAS_ROOT} ${ATLAS_DIR} $ENV{ATLAS_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /usr /usr/local/ /usr/local/opt # homebrew on mac /opt /opt/local /opt/ATLAS ) set(PATH_SUFFIXES_LIST lib64/atlas-sse3 #openSUSE 13.2 (Harlequin) lib64/atlas-sse2 #openSUSE 13.2 (Harlequin) lib64/atlas-sse #openSUSE 13.2 (Harlequin) lib64/atlas #openSUSE 13.2 (Harlequin) lib64 lib/atlas-sse3 #openSUSE 13.2 (Harlequin) lib/atlas-sse2 #openSUSE 13.2 (Harlequin) lib/atlas-sse #openSUSE 13.2 (Harlequin) lib/atlas #openSUSE 13.2 (Harlequin) lib ) if(APPLE) list(APPEND PATH_SUFFIXES_LIST openblas/lib) endif() # ============================================================================== # Prepare some helper variables set(ATLAS_INCLUDE_DIRS) set(ATLAS_LIBRARIES) set(ATLAS_THREAD_PREFIX "") if(ATLAS_REQUIRE_THREADED) set(ATLAS_THREAD_PREFIX "pt") endif() # ============================================================================== ## First try to find ATLAS with NO_MODULE, ## As of 20160706 version 0.2.18 there is limited cmake support for ATLAS ## that is not as complete as this version, if found, use it ## to identify the ATLAS_VERSION_STRING and improve searching. find_package(ATLAS NO_MODULE QUIET) if(ATLAS_VERSION) set(ATLAS_VERSION_STRING ${ATLAS_VERSION}) unset(ATLAS_VERSION) # Use cmake conventional naming endif() # ============================================================================== ### First search for headers find_path(ATLAS_CBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${ATLAS_SEARCH_PATHS} PATH_SUFFIXES include include/openblas) # ============================================================================== ### Second, search for libraries find_library(ATLAS_LIB NAMES atlas PATHS ${ATLAS_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST}) find_library(CBLAS_LIB NAMES ${ATLAS_THREAD_PREFIX}cblas PATHS ${LAPACKE_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST}) find_library(LAPACK_LIB NAMES ${ATLAS_THREAD_PREFIX}lapack PATHS ${LAPACKE_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST}) if(NOT DEFINED ATLAS_NO_LAPACKE OR NOT ATLAS_NO_LAPACKE) if(ATLAS_LIB) include(CheckLibraryExists) check_library_exists(${ATLAS_LIB} LAPACKE_cheev "" HAVE_LAPACKE_CHEEV) check_library_exists(${ATLAS_LIB} LAPACKE_zgesdd "" HAVE_LAPACKE_ZGESDD) if(NOT HAVE_LAPACKE_CHEEV OR NOT HAVE_LAPACKE_ZGESDD) message(WARNING "ATLAS has no LAPACKE symbols. Attempting to look for a LAPACKE library") find_package(LAPACKE QUIET REQUIRED COMPONENTS lapacke) list(APPEND ATLAS_LIBRARIES ${LAPACKE_LIBRARIES}) endif() endif() set(LAPACKE_LIB_VAR "LAPACKE_LIBRARIES") else() set(LAPACKE_LIB_VAR "") endif() find_library(F77BLAS_LIB NAMES ${ATLAS_THREAD_PREFIX}f77blas PATHS ${LAPACKE_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST}) # WARNING: We may not be able to determine the version of some ATLAS set(ATLAS_VERSION_MAJOR 0) set(ATLAS_VERSION_MINOR 0) set(ATLAS_VERSION_PATCH 0) if(ATLAS_VERSION_STRING) string(REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\1" ATLAS_VERSION_MAJOR "${ATLAS_VERSION_STRING}") string(REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\2" ATLAS_VERSION_MINOR "${ATLAS_VERSION_STRING}") string(REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\3" ATLAS_VERSION_PATCH "${ATLAS_VERSION_STRING}") elseif(ATLAS_LIB) set(ATLAS_VERSION_STRING "ATLAS.UNKOWN.VERSION") else() set(ATLAS_VERSION_STRING) endif() # ============================================================================== # Checks 'REQUIRED', 'QUIET' and versions. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ATLAS FOUND_VAR ATLAS_FOUND REQUIRED_VARS ATLAS_CBLAS_INCLUDE_DIR ${LAPACKE_INCLUDE_VAR} ${LAPACKE_LIB_VAR} LAPACK_LIB F77BLAS_LIB CBLAS_LIB ATLAS_LIB VERSION_VAR ATLAS_VERSION_STRING ) # ------------------------------------------------------------------------------ if (ATLAS_FOUND) list(APPEND ATLAS_INCLUDE_DIRS ${ATLAS_CBLAS_INCLUDE_DIR} ${ATLAS_CBLAS_INCLUDE_DIR}) list(REMOVE_DUPLICATES ATLAS_INCLUDE_DIRS) if("${CMAKE_C_COMPILER_ID}" MATCHES ".*Clang.*" OR "${CMAKE_C_COMPILER_ID}" MATCHES ".*GNU.*" OR "${CMAKE_C_COMPILER_ID}" MATCHES ".*Intel.*" ) #NOT MSVC set(MATH_LIB m) endif() list(APPEND ATLAS_LIBRARIES ${LAPACKE_LIBRARIES} ${LAPACK_LIB} ${F77BLAS_LIB} ${CBLAS_LIB} ${ATLAS_LIB} ${MATH_LIB}) if(NOT TARGET ATLAS::ATLAS) get_filename_component(LIB_EXT "${ATLAS_LIB}" EXT) if(LIB_EXT STREQUAL ".a" OR LIB_EXT STREQUAL ".lib") set(LIB_TYPE STATIC) else() set(LIB_TYPE SHARED) endif() add_library(ATLAS::ATLAS ${LIB_TYPE} IMPORTED GLOBAL) set(_tmp_dep_libs "${LAPACKE_LIBRARIES};${LAPACK_LIB};${F77BLAS_LIB};${CBLAS_LIB};${MATH_LIB}") list(REMOVE_DUPLICATES _tmp_dep_libs) set_target_properties(ATLAS::ATLAS PROPERTIES IMPORTED_LOCATION "${ATLAS_LIB}" INTERFACE_INCLUDE_DIRECTORIES "${ATLAS_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${_tmp_dep_libs}") endif() if(NOT ATLAS_FIND_QUIETLY) get_target_property(_dep_libs ATLAS::ATLAS INTERFACE_LINK_LIBRARIES) set(_version "${ATLAS_VERSION_STRING}") if(_version STREQUAL "ATLAS.UNKOWN.VERSION") set(_version) else() set(_version " (${_version})") endif() message(STATUS "Found ATLAS${_version} and defined the ATLAS::ATLAS imported target:") message(STATUS " - include: ${ATLAS_INCLUDE_DIRS}") message(STATUS " - library: ${ATLAS_LIB}") message(STATUS " - dependencies: ${_dep_libs}") endif() endif() # ============================================================================== mark_as_advanced( ATLAS_FOUND ATLAS_INCLUDE_DIRS ATLAS_LIBRARIES ATLAS_VERSION_MAJOR ATLAS_VERSION_MINOR ATLAS_VERSION_PATCH ATLAS_VERSION_STRING ) # ============================================================================== bart-0.5.00/cmake/FindBOpenMP.cmake000066400000000000000000000524311353046746100166650ustar00rootroot00000000000000# Taken from https://github.com/Kitware/CMake for CMake 3.12 # # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. #.rst: # FindBOpenMP # ---------- # # Finds OpenMP support # # This module can be used to detect OpenMP support in a compiler. If # the compiler supports OpenMP, the flags required to compile with # OpenMP support are returned in variables for the different languages. # The variables may be empty if the compiler does not need a special # flag to support OpenMP. # # Variables # ^^^^^^^^^ # # The module exposes the components ``C``, ``CXX``, and ``Fortran``. # Each of these controls the various languages to search OpenMP support for. # # Depending on the enabled components the following variables will be set: # # ``OpenMP_FOUND`` # Variable indicating that OpenMP flags for all requested languages have been found. # If no components are specified, this is true if OpenMP settings for all enabled languages # were detected. # ``OpenMP_VERSION`` # Minimal version of the OpenMP standard detected among the requested languages, # or all enabled languages if no components were specified. # # This module will set the following variables per language in your # project, where ```` is one of C, CXX, or Fortran: # # ``OpenMP__FOUND`` # Variable indicating if OpenMP support for ```` was detected. # ``OpenMP__FLAGS`` # OpenMP compiler flags for ````, separated by spaces. # # For linking with OpenMP code written in ````, the following # variables are provided: # # ``OpenMP__LIB_NAMES`` # :ref:`;-list ` of libraries for OpenMP programs for ````. # ``OpenMP__LIBRARY`` # Location of the individual libraries needed for OpenMP support in ````. # ``OpenMP__LIBRARIES`` # A list of libraries needed to link with OpenMP code written in ````. # # Additionally, the module provides :prop_tgt:`IMPORTED` targets: # # ``OpenMP::OpenMP_`` # Target for using OpenMP from ````. # # Specifically for Fortran, the module sets the following variables: # # ``OpenMP_Fortran_HAVE_OMPLIB_HEADER`` # Boolean indicating if OpenMP is accessible through ``omp_lib.h``. # ``OpenMP_Fortran_HAVE_OMPLIB_MODULE`` # Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module. # # The module will also try to provide the OpenMP version variables: # # ``OpenMP__SPEC_DATE`` # Date of the OpenMP specification implemented by the ```` compiler. # ``OpenMP__VERSION_MAJOR`` # Major version of OpenMP implemented by the ```` compiler. # ``OpenMP__VERSION_MINOR`` # Minor version of OpenMP implemented by the ```` compiler. # ``OpenMP__VERSION`` # OpenMP version implemented by the ```` compiler. # # The specification date is formatted as given in the OpenMP standard: # ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of # the OpenMP specification implemented by the ```` compiler. function(_BOPENMP_FLAG_CANDIDATES LANG) if(NOT BOpenMP_${LANG}_FLAG) unset(BOpenMP_FLAG_CANDIDATES) set(OMP_FLAG_GNU "-fopenmp") set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp") set(OMP_FLAG_AppleClang "-Xclang -fopenmp") set(OMP_FLAG_HP "+Oopenmp") if(WIN32) set(OMP_FLAG_Intel "-Qopenmp") elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND "${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528") set(OMP_FLAG_Intel "-openmp") else() set(OMP_FLAG_Intel "-qopenmp") endif() set(OMP_FLAG_MIPSpro "-mp") set(OMP_FLAG_MSVC "-openmp") set(OMP_FLAG_PathScale "-openmp") set(OMP_FLAG_NAG "-openmp") set(OMP_FLAG_Absoft "-openmp") set(OMP_FLAG_PGI "-mp") set(OMP_FLAG_Flang "-fopenmp") set(OMP_FLAG_SunPro "-xopenmp") set(OMP_FLAG_XL "-qsmp=omp") # Cray compiler activate OpenMP with -h omp, which is enabled by default. set(OMP_FLAG_Cray " " "-h omp") # If we know the correct flags, use those if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) set(BOpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") # Fall back to reasonable default tries otherwise else() set(BOpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ") endif() set(BOpenMP_${LANG}_FLAG_CANDIDATES "${BOpenMP_FLAG_CANDIDATES}" PARENT_SCOPE) else() set(BOpenMP_${LANG}_FLAG_CANDIDATES "${BOpenMP_${LANG}_FLAG}" PARENT_SCOPE) endif() endfunction() set(BOpenMP_C_CXX_TEST_SOURCE " #include int main() { #ifdef _OPENMP omp_get_max_threads(); return 0; #else breaks_on_purpose #endif } ") set(BOpenMP_Fortran_TEST_SOURCE " program test @BOpenMP_Fortran_INCLUDE_LINE@ !$ integer :: n n = omp_get_num_threads() end program test " ) function(_BOPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH) set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindBOpenMP) if("${LANG}" STREQUAL "C") set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c") file(WRITE "${SRC_FILE}" "${BOpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") elseif("${LANG}" STREQUAL "CXX") set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp") file(WRITE "${SRC_FILE}" "${BOpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}") elseif("${LANG}" STREQUAL "Fortran") set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90") file(WRITE "${SRC_FILE}_in" "${BOpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}") configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY) endif() set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE) endfunction() include(CMakeParseImplicitLinkInfo) function(_BOPENMP_GET_FLAGS LANG FLAG_MODE BOPENMP_FLAG_VAR BOPENMP_LIB_NAMES_VAR) _BOPENMP_FLAG_CANDIDATES("${LANG}") _BOPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" BOpenMPTryFlag _BOPENMP_TEST_SRC) unset(BOpenMP_VERBOSE_COMPILE_OPTIONS) if(WIN32) separate_arguments(BOpenMP_VERBOSE_OPTIONS WINDOWS_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}") else() separate_arguments(BOpenMP_VERBOSE_OPTIONS UNIX_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}") endif() foreach(_VERBOSE_OPTION IN LISTS BOpenMP_VERBOSE_OPTIONS) if(NOT _VERBOSE_OPTION MATCHES "^-Wl,") list(APPEND BOpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION}) endif() endforeach() foreach(BOPENMP_FLAG IN LISTS BOpenMP_${LANG}_FLAG_CANDIDATES) set(BOPENMP_FLAGS_TEST "${BOPENMP_FLAG}") if(BOpenMP_VERBOSE_COMPILE_OPTIONS) set(BOPENMP_FLAGS_TEST "${BOPENMP_FLAGS_TEST} ${BOpenMP_VERBOSE_COMPILE_OPTIONS}") # string(APPEND BOPENMP_FLAGS_TEST " ${BOpenMP_VERBOSE_COMPILE_OPTIONS}") endif() string(REGEX REPLACE "[-/=+]" "" BOPENMP_PLAIN_FLAG "${BOPENMP_FLAG}") try_compile( BOpenMP_COMPILE_RESULT_${FLAG_MODE}_${BOPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_BOPENMP_TEST_SRC} CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${BOPENMP_FLAGS_TEST}" LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} OUTPUT_VARIABLE BOpenMP_TRY_COMPILE_OUTPUT ) if(BOpenMP_COMPILE_RESULT_${FLAG_MODE}_${BOPENMP_PLAIN_FLAG}) set("${BOPENMP_FLAG_VAR}" "${BOPENMP_FLAG}" PARENT_SCOPE) if(CMAKE_${LANG}_VERBOSE_FLAG) unset(BOpenMP_${LANG}_IMPLICIT_LIBRARIES) unset(BOpenMP_${LANG}_IMPLICIT_LINK_DIRS) unset(BOpenMP_${LANG}_IMPLICIT_FWK_DIRS) unset(BOpenMP_${LANG}_LOG_VAR) file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${BOpenMP_TRY_COMPILE_OUTPUT}\n\n") cmake_parse_implicit_link_info("${BOpenMP_TRY_COMPILE_OUTPUT}" BOpenMP_${LANG}_IMPLICIT_LIBRARIES BOpenMP_${LANG}_IMPLICIT_LINK_DIRS BOpenMP_${LANG}_IMPLICIT_FWK_DIRS BOpenMP_${LANG}_LOG_VAR "${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}" ) file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Parsed ${LANG} OpenMP implicit link information from above output:\n${BOpenMP_${LANG}_LOG_VAR}\n\n") unset(_BOPENMP_LIB_NAMES) foreach(_BOPENMP_IMPLICIT_LIB IN LISTS BOpenMP_${LANG}_IMPLICIT_LIBRARIES) get_filename_component(_BOPENMP_IMPLICIT_LIB_DIR "${_BOPENMP_IMPLICIT_LIB}" DIRECTORY) get_filename_component(_BOPENMP_IMPLICIT_LIB_NAME "${_BOPENMP_IMPLICIT_LIB}" NAME) get_filename_component(_BOPENMP_IMPLICIT_LIB_PLAIN "${_BOPENMP_IMPLICIT_LIB}" NAME_WE) string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _BOPENMP_IMPLICIT_LIB_PLAIN_ESC "${_BOPENMP_IMPLICIT_LIB_PLAIN}") string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _BOPENMP_IMPLICIT_LIB_PATH_ESC "${_BOPENMP_IMPLICIT_LIB}") list (FIND CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES "${_BOPENMP_IMPLICIT_LIB}" _index) if(NOT ( _index GREATER -1 OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_BOPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_BOPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_BOPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_BOPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) ) if(_BOPENMP_IMPLICIT_LIB_DIR) set(BOpenMP_${_BOPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_BOPENMP_IMPLICIT_LIB}" CACHE FILEPATH "Path to the ${_BOPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP") else() find_library(BOpenMP_${_BOPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY NAMES "${_BOPENMP_IMPLICIT_LIB_NAME}" DOC "Path to the ${_BOPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP" HINTS ${BOpenMP_${LANG}_IMPLICIT_LINK_DIRS} CMAKE_FIND_ROOT_PATH_BOTH NO_DEFAULT_PATH ) endif() mark_as_advanced(BOpenMP_${_BOPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY) list(APPEND _BOPENMP_LIB_NAMES ${_BOPENMP_IMPLICIT_LIB_PLAIN}) endif() endforeach() set("${BOPENMP_LIB_NAMES_VAR}" "${_BOPENMP_LIB_NAMES}" PARENT_SCOPE) else() set("${BOPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE) endif() break() elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0") find_library(BOpenMP_libomp_LIBRARY NAMES omp gomp iomp5 HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES} ) mark_as_advanced(BOpenMP_libomp_LIBRARY) if(BOpenMP_libomp_LIBRARY) try_compile( BOpenMP_COMPILE_RESULT_${FLAG_MODE}_${BOPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_BOPENMP_TEST_SRC} CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${BOPENMP_FLAGS_TEST}" LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${BOpenMP_libomp_LIBRARY} OUTPUT_VARIABLE BOpenMP_TRY_COMPILE_OUTPUT ) if(BOpenMP_COMPILE_RESULT_${FLAG_MODE}_${BOPENMP_PLAIN_FLAG}) set("${BOPENMP_FLAG_VAR}" "${BOPENMP_FLAG}" PARENT_SCOPE) set("${BOPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE) break() endif() endif() endif() set("${BOPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE) set("${BOPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE) endforeach() unset(BOpenMP_VERBOSE_COMPILE_OPTIONS) endfunction() set(BOpenMP_C_CXX_CHECK_VERSION_SOURCE " #include #include const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-', 'd', 'a', 't', 'e', '[', ('0' + ((_OPENMP/100000)%10)), ('0' + ((_OPENMP/10000)%10)), ('0' + ((_OPENMP/1000)%10)), ('0' + ((_OPENMP/100)%10)), ('0' + ((_OPENMP/10)%10)), ('0' + ((_OPENMP/1)%10)), ']', '\\0' }; int main() { puts(ompver_str); return 0; } ") set(BOpenMP_Fortran_CHECK_VERSION_SOURCE " program omp_ver @BOpenMP_Fortran_INCLUDE_LINE@ integer, parameter :: zero = ichar('0') integer, parameter :: ompv = openmp_version character, dimension(24), parameter :: ompver_str =& (/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',& 'd', 'a', 't', 'e', '[',& char(zero + mod(ompv/100000, 10)),& char(zero + mod(ompv/10000, 10)),& char(zero + mod(ompv/1000, 10)),& char(zero + mod(ompv/100, 10)),& char(zero + mod(ompv/10, 10)),& char(zero + mod(ompv/1, 10)), ']' /) print *, ompver_str end program omp_ver ") function(_BOPENMP_GET_SPEC_DATE LANG SPEC_DATE) _BOPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" BOpenMPCheckVersion _BOPENMP_TEST_SRC) set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindBOpenMP/ompver_${LANG}.bin") string(REGEX REPLACE "[-/=+]" "" BOPENMP_PLAIN_FLAG "${BOPENMP_FLAG}") try_compile(BOpenMP_SPECTEST_${LANG}_${BOPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_BOPENMP_TEST_SRC}" CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${BOpenMP_${LANG}_FLAGS}" COPY_FILE ${BIN_FILE}) if(${BOpenMP_SPECTEST_${LANG}_${BOPENMP_PLAIN_FLAG}}) file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date") set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*") if("${specstr}" MATCHES "${regex_spec_date}") set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE) endif() endif() endfunction() macro(_BOPENMP_SET_VERSION_BY_SPEC_DATE LANG) set(BOpenMP_SPEC_DATE_MAP "201611=5.0" "201511=4.5" "201307=4.0" "201107=3.1" "200805=3.0" "200505=2.5" "200203=2.0" "200011=2.0" "199911=1.1" "199810=1.0" "199710=1.0" ) if(BOpenMP_${LANG}_SPEC_DATE) string(REGEX MATCHALL "${BOpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${BOpenMP_SPEC_DATE_MAP}") else() set(_version_match "") endif() if(NOT _version_match STREQUAL "") set(BOpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1}) set(BOpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2}) set(BOpenMP_${LANG}_VERSION "${BOpenMP_${LANG}_VERSION_MAJOR}.${BOpenMP_${LANG}_VERSION_MINOR}") else() unset(BOpenMP_${LANG}_VERSION_MAJOR) unset(BOpenMP_${LANG}_VERSION_MINOR) unset(BOpenMP_${LANG}_VERSION) endif() unset(_version_match) unset(BOpenMP_SPEC_DATE_MAP) endmacro() foreach(LANG IN ITEMS C CXX) if(CMAKE_${LANG}_COMPILER_LOADED) if(NOT DEFINED BOpenMP_${LANG}_FLAGS OR "${BOpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND" OR NOT DEFINED BOpenMP_${LANG}_LIB_NAMES OR "${BOpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") _BOPENMP_GET_FLAGS("${LANG}" "${LANG}" BOpenMP_${LANG}_FLAGS_WORK BOpenMP_${LANG}_LIB_NAMES_WORK) endif() set(BOpenMP_${LANG}_FLAGS "${BOpenMP_${LANG}_FLAGS_WORK}" CACHE STRING "${LANG} compiler flags for OpenMP parallelization") set(BOpenMP_${LANG}_LIB_NAMES "${BOpenMP_${LANG}_LIB_NAMES_WORK}" CACHE STRING "${LANG} compiler libraries for OpenMP parallelization") mark_as_advanced(BOpenMP_${LANG}_FLAGS BOpenMP_${LANG}_LIB_NAMES) endif() endforeach() if(CMAKE_Fortran_COMPILER_LOADED) if(NOT DEFINED BOpenMP_Fortran_FLAGS OR "${BOpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND" OR NOT DEFINED BOpenMP_Fortran_LIB_NAMES OR "${BOpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND" OR NOT DEFINED BOpenMP_Fortran_HAVE_OMPLIB_MODULE) set(BOpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none") _BOPENMP_GET_FLAGS("Fortran" "FortranHeader" BOpenMP_Fortran_FLAGS_WORK BOpenMP_Fortran_LIB_NAMES_WORK) if(BOpenMP_Fortran_FLAGS_WORK) set(BOpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "") endif() set(BOpenMP_Fortran_FLAGS "${BOpenMP_Fortran_FLAGS_WORK}" CACHE STRING "Fortran compiler flags for OpenMP parallelization") set(BOpenMP_Fortran_LIB_NAMES "${BOpenMP_Fortran_LIB_NAMES_WORK}" CACHE STRING "Fortran compiler libraries for OpenMP parallelization") mark_as_advanced(BOpenMP_Fortran_FLAGS BOpenMP_Fortran_LIB_NAMES) endif() if(NOT DEFINED BOpenMP_Fortran_FLAGS OR "${BOpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND" OR NOT DEFINED BOpenMP_Fortran_LIB_NAMES OR "${BOpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND" OR NOT DEFINED BOpenMP_Fortran_HAVE_OMPLIB_HEADER) set(BOpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") _BOPENMP_GET_FLAGS("Fortran" "FortranModule" BOpenMP_Fortran_FLAGS_WORK BOpenMP_Fortran_LIB_NAMES_WORK) if(BOpenMP_Fortran_FLAGS_WORK) set(BOpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "") endif() set(BOpenMP_Fortran_FLAGS "${BOpenMP_Fortran_FLAGS_WORK}" CACHE STRING "Fortran compiler flags for OpenMP parallelization") set(BOpenMP_Fortran_LIB_NAMES "${BOpenMP_Fortran_LIB_NAMES}" CACHE STRING "Fortran compiler libraries for OpenMP parallelization") endif() if(BOpenMP_Fortran_HAVE_OMPLIB_MODULE) set(BOpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none") else() set(BOpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'") endif() endif() if(NOT BOpenMP_FIND_COMPONENTS) set(BOpenMP_FINDLIST C CXX Fortran) else() set(BOpenMP_FINDLIST ${BOpenMP_FIND_COMPONENTS}) endif() unset(_BOpenMP_MIN_VERSION) include(FindPackageHandleStandardArgs) foreach(LANG IN LISTS BOpenMP_FINDLIST) if(CMAKE_${LANG}_COMPILER_LOADED) if (NOT BOpenMP_${LANG}_SPEC_DATE AND BOpenMP_${LANG}_FLAGS) _BOPENMP_GET_SPEC_DATE("${LANG}" BOpenMP_${LANG}_SPEC_DATE_INTERNAL) set(BOpenMP_${LANG}_SPEC_DATE "${BOpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE INTERNAL "${LANG} compiler's OpenMP specification date") _BOPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}") endif() set(BOpenMP_${LANG}_FIND_QUIETLY ${BOpenMP_FIND_QUIETLY}) set(BOpenMP_${LANG}_FIND_REQUIRED ${BOpenMP_FIND_REQUIRED}) set(BOpenMP_${LANG}_FIND_VERSION ${BOpenMP_FIND_VERSION}) set(BOpenMP_${LANG}_FIND_VERSION_EXACT ${BOpenMP_FIND_VERSION_EXACT}) set(_BOPENMP_${LANG}_REQUIRED_VARS BOpenMP_${LANG}_FLAGS) if("${BOpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND") set(_BOPENMP_${LANG}_REQUIRED_LIB_VARS BOpenMP_${LANG}_LIB_NAMES) else() foreach(_BOPENMP_IMPLICIT_LIB IN LISTS BOpenMP_${LANG}_LIB_NAMES) list(APPEND _BOPENMP_${LANG}_REQUIRED_LIB_VARS BOpenMP_${_BOPENMP_IMPLICIT_LIB}_LIBRARY) endforeach() endif() find_package_handle_standard_args(BOpenMP_${LANG} FOUND_VAR BOpenMP_${LANG}_FOUND REQUIRED_VARS BOpenMP_${LANG}_FLAGS ${_BOPENMP_${LANG}_REQUIRED_LIB_VARS} VERSION_VAR BOpenMP_${LANG}_VERSION ) if(BOpenMP_${LANG}_FOUND) if(DEFINED BOpenMP_${LANG}_VERSION) if(NOT _BOpenMP_MIN_VERSION OR _BOpenMP_MIN_VERSION VERSION_GREATER BOpenMP_${LANG}_VERSION) set(_BOpenMP_MIN_VERSION BOpenMP_${LANG}_VERSION) endif() endif() set(BOpenMP_${LANG}_LIBRARIES "") foreach(_BOPENMP_IMPLICIT_LIB IN LISTS BOpenMP_${LANG}_LIB_NAMES) list(APPEND BOpenMP_${LANG}_LIBRARIES "${BOpenMP_${_BOPENMP_IMPLICIT_LIB}_LIBRARY}") endforeach() if(NOT TARGET OpenMP::OpenMP_${LANG}) if(CMAKE_VERSION VERSION_LESS 3.0) add_library(OpenMP::OpenMP_${LANG} UNKNOWN IMPORTED) list(GET BOpenMP_${LANG}_LIB_NAMES 0 _name) set_target_properties(OpenMP::OpenMP_${LANG} PROPERTIES IMPORTED_LOCATION "${BOpenMP_${_name}_LIBRARY}") else() add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED) endif() endif() if(BOpenMP_${LANG}_FLAGS) if(WIN32) separate_arguments(_BOpenMP_${LANG}_OPTIONS WINDOWS_COMMAND "${BOpenMP_${LANG}_FLAGS}") else() separate_arguments(_BOpenMP_${LANG}_OPTIONS UNIX_COMMAND "${BOpenMP_${LANG}_FLAGS}") endif() if(CMAKE_VERSION VERSION_LESS 3.3) set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${_BOpenMP_${LANG}_OPTIONS}") else() set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "$<$:${_BOpenMP_${LANG}_OPTIONS}>") endif() unset(_BOpenMP_${LANG}_OPTIONS) endif() if(BOpenMP_${LANG}_LIBRARIES) set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY INTERFACE_LINK_LIBRARIES "${BOpenMP_${LANG}_LIBRARIES}") endif() endif() endif() endforeach() unset(_BOpenMP_REQ_VARS) foreach(LANG IN ITEMS C CXX Fortran) list (FIND BOpenMP_FIND_COMPONENTS "${LANG}" _index) if((NOT BOpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR _index GREATER -1) list(APPEND _BOpenMP_REQ_VARS "BOpenMP_${LANG}_FOUND") endif() endforeach() find_package_handle_standard_args(BOpenMP FOUND_VAR BOpenMP_FOUND REQUIRED_VARS ${_BOpenMP_REQ_VARS} VERSION_VAR ${_BOpenMP_MIN_VERSION} HANDLE_COMPONENTS) set(BOPENMP_FOUND ${BOpenMP_FOUND}) if(CMAKE_Fortran_COMPILER_LOADED AND BOpenMP_Fortran_FOUND) if(NOT DEFINED BOpenMP_Fortran_HAVE_OMPLIB_MODULE) set(BOpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "") endif() if(NOT DEFINED BOpenMP_Fortran_HAVE_OMPLIB_HEADER) set(BOpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "") endif() endif() if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED )) message(SEND_ERROR "FindBOpenMP requires the C, CXX or Fortran languages to be enabled") endif() unset(BOpenMP_C_CXX_TEST_SOURCE) unset(BOpenMP_Fortran_TEST_SOURCE) unset(BOpenMP_C_CXX_CHECK_VERSION_SOURCE) unset(BOpenMP_Fortran_CHECK_VERSION_SOURCE) unset(BOpenMP_Fortran_INCLUDE_LINE) bart-0.5.00/cmake/FindBPython.cmake000066400000000000000000000153771353046746100170200ustar00rootroot00000000000000# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. #[=======================================================================[.rst: # FindBPython # ---------- # Find Python interpreter, compiler and development environment (include # directories and libraries). # Three components are supported: # * ``Interpreter``: search for Python interpreter. # * ``Compiler``: search for Python compiler. Only offered by IronPython. # * ``Development``: search for development artifacts (include directories and # libraries). # If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. # To ensure consistent versions between components ``Interpreter``, ``Compiler`` # and ``Development``, specify all components at the same time:: # find_package (BPython COMPONENTS Interpreter Development) # This module looks preferably for version 3 of Python. If not found, version 2 # is searched. # To manage concurrent versions 3 and 2 of Python, use :module:`FindBPython3` and # :module:`FindBPython2` modules rather than this one. # Imported Targets # ^^^^^^^^^^^^^^^^ # This module defines the following :ref:`Imported Targets `: # ``Python::Interpreter`` # Python interpreter. Target defined if component ``Interpreter`` is found. # ``Python::Compiler`` # Python compiler. Target defined if component ``Compiler`` is found. # ``Python::Python`` # Python library. Target defined if component ``Development`` is found. # Result Variables # ^^^^^^^^^^^^^^^^ # This module will set the following variables in your project # (see :ref:`Standard Variable Names `): # ``Python_FOUND`` # System has the Python requested components. # ``Python_Interpreter_FOUND`` # System has the Python interpreter. # ``Python_EXECUTABLE`` # Path to the Python interpreter. # ``Python_INTERPRETER_ID`` # A short string unique to the interpreter. Possible values include: # * Python # * ActivePython # * Anaconda # * Canopy # * IronPython # ``Python_STDLIB`` # Standard platform independent installation directory. # Information returned by # ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. # ``Python_STDARCH`` # Standard platform dependent installation directory. # Information returned by # ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. # ``Python_SITELIB`` # Third-party platform independent installation directory. # Information returned by # ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. # ``Python_SITEARCH`` # Third-party platform dependent installation directory. # Information returned by # ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. # ``Python_Compiler_FOUND`` # System has the Python compiler. # ``Python_COMPILER`` # Path to the Python compiler. Only offered by IronPython. # ``Python_COMPILER_ID`` # A short string unique to the compiler. Possible values include: # * IronPython # ``Python_Development_FOUND`` # System has the Python development artifacts. # ``Python_INCLUDE_DIRS`` # The Python include directories. # ``Python_LIBRARIES`` # The Python libraries. # ``Python_LIBRARY_DIRS`` # The Python library directories. # ``Python_RUNTIME_LIBRARY_DIRS`` # The Python runtime library directories. # ``Python_VERSION`` # Python version. # ``Python_VERSION_MAJOR`` # Python major version. # ``Python_VERSION_MINOR`` # Python minor version. # ``Python_VERSION_PATCH`` # Python patch version. # Hints # ^^^^^ # ``Python_ROOT_DIR`` # Define the root directory of a Python installation. # ``Python_USE_STATIC_LIBS`` # * If not defined, search for shared libraries and static libraries in that # order. # * If set to TRUE, search **only** for static libraries. # * If set to FALSE, search **only** for shared libraries. # Commands # ^^^^^^^^ # This module defines the command ``Python_add_library`` which have the same # semantic as :command:`add_library` but take care of Python module naming rules # (only applied if library is of type ``MODULE``) and add dependency to target # ``Python::Python``:: # Python_add_library (my_module MODULE src1.cpp) # If library type is not specified, ``MODULE`` is assumed. #]=======================================================================] set(_PYTHON_PREFIX Python) set(Python_FIND_REQUIRED ${BPython_FIND_REQUIRED}) set(Python_FIND_QUIETLY ${BPython_FIND_QUIETLY}) set(Python_FIND_VERSION ${BPython_FIND_VERSION}) set(Python_FIND_VERSION_MAJOR ${BPython_FIND_VERSION_MAJOR}) set(Python_FIND_VERSION_MINOR ${BPython_FIND_VERSION_MINOR}) set(Python_FIND_VERSION_PATCH ${BPython_FIND_VERSION_PATCH}) set(Python_FIND_VERSION_TWEAK ${BPython_FIND_VERSION_TWEAK}) set(Python_FIND_VERSION_COUNT ${BPython_FIND_VERSION_COUNT}) set(Python_FIND_VERSION_EXACT ${BPython_FIND_VERSION_EXACT}) set(Python_FIND_COMPONENTS ${BPython_FIND_COMPONENTS}) foreach(_comp ${BPython_FIND_COMPONENTS}) set(Python_FIND_REQUIRED_${_comp} ${BPython_FIND_REQUIRED_${_comp}}) endforeach() if (DEFINED Python_FIND_VERSION) set (_Python_REQUIRED_VERSION_MAJOR ${Python_FIND_VERSION_MAJOR}) include (${CMAKE_CURRENT_LIST_DIR}/FindPythonSupport.cmake) else() # iterate over versions in quiet and NOT required modes to avoid multiple # "Found" messages and prematurally failure. set (_Python_QUIETLY ${BPython_FIND_QUIETLY}) set (_Python_REQUIRED ${BPython_FIND_REQUIRED}) set (Python_FIND_QUIETLY TRUE) set (Python_FIND_REQUIRED FALSE) set (_Python_REQUIRED_VERSIONS 3 2) set (_Python_REQUIRED_VERSION_LAST 2) foreach (_Python_REQUIRED_VERSION_MAJOR IN LISTS _Python_REQUIRED_VERSIONS) set (Python_FIND_VERSION ${_Python_REQUIRED_VERSION_MAJOR}) include (${CMAKE_CURRENT_LIST_DIR}/FindPythonSupport.cmake) if (Python_FOUND OR _Python_REQUIRED_VERSION_MAJOR EQUAL _Python_REQUIRED_VERSION_LAST) break() endif() # clean-up some CACHE variables to ensure look-up restart from scratch foreach (_Python_ITEM IN LISTS _Python_CACHED_VARS) unset (${_Python_ITEM} CACHE) endforeach() endforeach() unset (Python_FIND_VERSION) set (BPython_FIND_QUIETLY ${_Python_QUIETLY}) set (BPython_FIND_REQUIRED ${_Python_REQUIRED}) if (Python_FIND_REQUIRED OR NOT Python_FIND_QUIETLY) # call again validation command to get "Found" or error message find_package_handle_standard_args (Python HANDLE_COMPONENTS REQUIRED_VARS ${_Python_REQUIRED_VARS} VERSION_VAR Python_VERSION) endif() endif() if (COMMAND __Python_add_library) macro (Python_add_library) __Python_add_library (Python ${ARGV}) endmacro() endif() unset (_PYTHON_PREFIX) bart-0.5.00/cmake/FindCUDAlibs.cmake000066400000000000000000000233261353046746100170140ustar00rootroot00000000000000#.rst: # FindCUDAlibs # ------------- # # Find CUDA include dirs and libraries # # Use this module by invoking find_package with the form:: # # find_package(CUDAlibs # [REQUIRED] # Fail with error if LAPACKE is not found # [COMPONENTS ...] # List of components to look for # ) # Not specifying any components is equivalent to # looking for the BASIC libraries # # Valid names for COMPONENTS libraries are:: # # ALL - Find all libraries # BASIC - Equivalent to CUDART;CUBLAS;CUFFT # # CUDART - CUDA RT library # CUBLAS - CUDA BLAS library # CUFFT - CUDA FFT library # CUFFTW - CUDA FFTW library # CUPTI - CUDA Profiling Tools Interface library. # CURAND - CUDA Random Number Generation library. # CUSOLVER - CUDA Direct Solver library. # CUSPARSE - CUDA Sparse Matrix library. # NPP - NVIDIA Performance Primitives lib. # NPPC - NVIDIA Performance Primitives lib (core). # NPPI - NVIDIA Performance Primitives lib (image processing). # NPPIAL - NVIDIA Performance Primitives lib (image processing). # NPPICC - NVIDIA Performance Primitives lib (image processing). # NPPICOM - NVIDIA Performance Primitives lib (image processing). # NPPIDEI - NVIDIA Performance Primitives lib (image processing). # NPPIF - NVIDIA Performance Primitives lib (image processing). # NPPIG - NVIDIA Performance Primitives lib (image processing). # NPPIM - NVIDIA Performance Primitives lib (image processing). # NPPIST - NVIDIA Performance Primitives lib (image processing). # NPPISU - NVIDIA Performance Primitives lib (image processing). # NPPITC - NVIDIA Performance Primitives lib (image processing). # NPPS - NVIDIA Performance Primitives lib (signal processing). # NVBLAS - NVIDIA BLAS library # # Not specifying COMPONENTS is identical to choosing ALL # # This module reads hints about search locations from variables # (either CMake variables or environment variables):: # # CUDA_TOOLKIT_ROOT_DIR # CUDA_ROOT # # The following :prop_tgt:`IMPORTED` targets are defined if required:: # # CUDAlibs::CUDART - Imported target for the CUDA RT library # CUDAlibs::CUBLAS - Imported target for the CUDA cublas library # CUDAlibs::CUFFT - Imported target for the CUDA cufft library # CUDAlibs::CUFFTW - Imported target for the CUDA cufftw library # CUDAlibs::CUPTI - Imported target for the CUDA cupti library # CUDAlibs::CURAND - Imported target for the CUDA curand library # CUDAlibs::CUSOLVER - Imported target for the CUDA cusolver library # CUDAlibs::CUSPARSE - Imported target for the CUDA cusparse library # CUDAlibs::NPP - Imported target for the CUDA npp library # CUDAlibs::NPPC - Imported target for the CUDA nppc library # CUDAlibs::NPPI - Imported target for the CUDA nppi library # CUDAlibs::NPPIAL - Imported target for the CUDA nppial library # CUDAlibs::NPPICC - Imported target for the CUDA nppicc library # CUDAlibs::NPPICOM - Imported target for the CUDA nppicom library # CUDAlibs::NPPIDEI - Imported target for the CUDA nppidei library # CUDAlibs::NPPIF - Imported target for the CUDA nppif library # CUDAlibs::NPPIG - Imported target for the CUDA nppig library # CUDAlibs::NPPIM - Imported target for the CUDA nppim library # CUDAlibs::NPPIST - Imported target for the CUDA nppist library # CUDAlibs::NPPISU - Imported target for the CUDA nppisu library # CUDAlibs::NPPITC - Imported target for the CUDA nppitc library # CUDAlibs::NPPS - Imported target for the CUDA npps library # CUDAlibs::NVBLAS - Imported target for the CUDA nvblas library # # ============================================================================== # Copyright 2018 Damien Nguyen # # Distributed under the OSI-approved BSD License (the "License") # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ============================================================================== if(CMAKE_VERSION VERSION_LESS 3.8) message(FATAL_ERROR "Cannot use find_package(CUDAlibs ...) with CMake < 3.8! Use find_package(CUDA) instead.") endif() # ------------------------------------------------------------------------------ set(_cuda_root_dir_hint) foreach(_dir ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}) get_filename_component(_dirname "${_dir}" DIRECTORY) list(APPEND _cuda_root_dir_hint ${_dirname}) endforeach() set(CUDAlibs_SEARCH_PATHS ${_cuda_root_dir_hint} ${CUDA_ROOT} $ENV{CUDA_ROOT} ${CUDA_TOOLKIT_ROOT_DIR} $ENV{CUDA_TOOLKIT_ROOT_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /usr /usr/local /usr/local/cuda /opt /opt/local ) set(PATH_SUFFIXES_LIST lib/x64 lib64 libx64 lib lib/Win32 lib libWin32) if(WIN32) set(_root_dir "C:/Program\ Files/NVIDIA\ GPU\ Computing\ Toolkit/CUDA") file(GLOB _children RELATIVE ${_root_dir} ${_root_dir}/*) list(SORT _children) list(REVERSE _children) foreach(_child ${_children}) if(IS_DIRECTORY ${_root_dir}/${_child} AND ${_child} MATCH "v[0-9]+.[0-9]") list(APPEND CUDAlibs_SEARCH_PATHS ${_root_dir}/${child}) endif() endforeach() endif() # ============================================================================== # Prepare some helper variables set(CUDAlibs_REQUIRED_VARS) # ============================================================================== macro(cuda_find_library component) string(TOLOWER ${COMPONENT} libnames) find_library(CUDAlibs_${component}_LIB NAMES ${libnames} PATHS ${CUDAlibs_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST} NO_DEFAULT_PATH) if(CUDAlibs_${component}_LIB) set(CUDAlibs_${component}_LIB_FOUND 1) endif() list(APPEND CUDAlibs_REQUIRED_VARS "CUDAlibs_${component}_LIB") if(CUDAlibs_${component}_LIB_FOUND) set(CUDAlibs_${component}_FOUND 1) else() set(CUDAlibs_${component}_FOUND 0) endif() endmacro() # ------------------------------------------------------------------------------ set(CUDAlibs_ALL_LIBS "CUDART;CUBLAS;CUFFT;CUFFTW;CUPTI;CURAND;CUSOLVER;CUSPARSE;NPP;NPPC;NPPI;NPPIAL;NPPICC;NPPICOM;NPPIDEI;NPPIF;NPPIG;NPPIM;NPPIST;NPPISU;NPPITC;NPPS;NVBLAS") # List dependent libraries for relevant targets set(CUDAlibs_DEP_CUFFTW "CUFFT") set(CUDAlibs_DEP_NPPIAL "NPPC") set(CUDAlibs_DEP_NPPICC "NPPC") set(CUDAlibs_DEP_NPPICOM "NPPC") set(CUDAlibs_DEP_NPPIDEI "NPPC") set(CUDAlibs_DEP_NPPIF "NPPC") set(CUDAlibs_DEP_NPPIG "NPPC") set(CUDAlibs_DEP_NPPIM "NPPC") set(CUDAlibs_DEP_NPPIST "NPPC") set(CUDAlibs_DEP_NPPISU "NPPC") set(CUDAlibs_DEP_NPPITC "NPPC") set(CUDAlibs_DEP_NPPS "NPPC") set(CUDAlibs_DEP_NVBLAS "CUBLAS") # ------------------------------------------------------------------------------ if(NOT CUDAlibs_FIND_COMPONENTS OR CUDAlibs_FIND_COMPONENTS STREQUAL "BASIC") set(CUDAlibs_FIND_COMPONENTS "CUDART;CUBLAS;CUFFT") elseif(CUDAlibs_FIND_COMPONENTS STREQUAL "ALL") set(CUDAlibs_FIND_COMPONENTS ${CUDAlibs_ALL_LIBS}) endif() foreach(COMPONENT ${CUDAlibs_FIND_COMPONENTS}) string(TOUPPER ${COMPONENT} UPPERCOMPONENT) if (${UPPERCOMPONENT} IN_LIST CUDAlibs_ALL_LIBS) cuda_find_library(${UPPERCOMPONENT}) foreach(_dep "${CUDAlibs_DEP_${UPPERCOMPONENT}}") if(NOT "${_dep}" STREQUAL "") cuda_find_library(${_dep}) endif() endforeach() else() message(FATAL_ERROR "Unknown component: ${COMPONENT}") endif() mark_as_advanced( CUDAlibs_${UPPERCOMPONENT}_LIB CUDAlibs_${UPPERCOMPONENT}_INCLUDE_DIR) endforeach() # ============================================================================== include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CUDAlibs FOUND_VAR CUDAlibs_FOUND REQUIRED_VARS ${CUDAlibs_REQUIRED_VARS} HANDLE_COMPONENTS) # ============================================================================== if(CUDAlibs_FOUND) # Inspired by FindBoost.cmake foreach(COMPONENT ${CUDAlibs_FIND_COMPONENTS}) string(TOUPPER ${COMPONENT} UPPERCOMPONENT) if(NOT TARGET CUDAlibs::${UPPERCOMPONENT} AND CUDAlibs_${UPPERCOMPONENT}_FOUND) get_filename_component(LIB_EXT "${CUDAlibs_${UPPERCOMPONENT}_LIB}" EXT) if(LIB_EXT STREQUAL ".a" OR LIB_EXT STREQUAL ".lib") set(LIB_TYPE STATIC) else() set(LIB_TYPE SHARED) endif() add_library(CUDAlibs::${UPPERCOMPONENT} ${LIB_TYPE} IMPORTED GLOBAL) set_target_properties(CUDAlibs::${UPPERCOMPONENT} PROPERTIES IMPORTED_LOCATION "${CUDAlibs_${UPPERCOMPONENT}_LIB}" INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}") # ------------------------------------------------------------------------ set(_dependent_libraries) foreach(_dep "${CUDAlibs_DEP_${UPPERCOMPONENT}}") list(APPEND _dependent_libraries ${_dep}) endforeach() if(NOT "${_dependent_libraries}" STREQUAL "") message(STATUS "Adding dependencies: ${_dependent_libraries}") set_target_properties(CUDAlibs::${UPPERCOMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES "${_dependent_libraries}") endif() endif() endforeach() # ---------------------------------------------------------------------------- if(NOT CUDAlibs_FIND_QUIETLY) message(STATUS "Found CUDAlibs and defined the following imported targets:") foreach(_comp ${CUDAlibs_FIND_COMPONENTS}) message(STATUS " - CUDAlibs::${_comp}") endforeach() endif() endif() # ============================================================================== mark_as_advanced( CUDAlibs_FOUND ) bart-0.5.00/cmake/FindFFTW.cmake000066400000000000000000000165451353046746100162010ustar00rootroot00000000000000#.rst: # FindFFTW # ------------- # # Find FFTW3 include dirs and libraries # # Use this module by invoking find_package with the form:: # # find_package(Boost # [REQUIRED] # Fail with error if FFTW is not found # [VERSION [2,3]] # Version of FFTW to look for (only considers major version) # [COMPONENTS ...] # List of libraries to look for # ) # # Valid names for COMPONENTS libraries are:: # # ALL - Find all libraries # FFTW - Find a FFTW (double) library # FFTW_MT - Find a FFTW multi-threaded (double) library # FFTWF - Find a FFTW (single) library # FFTWF_MT - Find a FFTW multi-threaded (single) library # # Not specifying COMPONENTS is identical to choosing ALL # # This module defines:: # # FFTW_FOUND - True if headers and requested libraries were found # FFTW_VERSION - Version of the FFTW libraries # FFTW_INCLUDE_DIRS - FFTW include directories # FFTW_LIBRARIES - FFTW component libraries to be linked # # # This module reads hints about search locations from variables # (either CMake variables or environment variables):: # # FFTW_ROOT - Preferred installation prefix for FFTW # FFTW_DIR - Preferred installation prefix for FFTW # # # The following :prop_tgt:`IMPORTED` targets are also defined:: # # FFTW::FFTW - Imported target for the FFTW (double) library # FFTW::FFTW_MT - Imported target for the FFTW multi-thread (double) library # FFTW::FFTWF - Imported target for the FFTW (single) library # FFTW::FFTWF_MT - Imported target for the FFTW multi-thread (single) library # # ============================================================================== # Copyright 2018 Damien Nguyen # # Distributed under the OSI-approved BSD License (the "License") # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ============================================================================== set(FFTW_SEARCH_PATHS ${FFTW_ROOT} $ENV{FFTW_ROOT} ${FFTW_DIR} $ENV{FFTW_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /sw /usr /usr/local/ /usr/local/opt # homebrew on mac /opt /opt/local /opt/FFTW ) set(INC_PATH_SUFFIXES_LIST include include/fftw include/fftw3 ) set(LIB_PATH_SUFFIXES_LIST lib64 lib lib/fftw lib/x86_64-linux-gnu lib32 ) # ============================================================================== # Prepare some helper variables set(FFTW_REQUIRED_VARS) set(FFTW_INCLUDE_DIRS) set(FFTW_LIBRARIES) # ============================================================================== macro(_find_library_with_header component libnames incnames) find_library(FFTW_${component}_LIB NAMES ${libnames} PATHS ${FFTW_SEARCH_PATHS} PATH_SUFFIXES ${LIB_PATH_SUFFIXES_LIST}) if(FFTW_${component}_LIB) set(FFTW_${component}_LIB_FOUND 1) endif() list(APPEND FFTW_REQUIRED_VARS "FFTW_${component}_LIB") # If necessary, look for the header file as well if(NOT "${incnames}" STREQUAL "") find_path(FFTW_${component}_INCLUDE_DIR NAMES ${incnames} PATHS ${FFTW_SEARCH_PATHS} PATH_SUFFIXES ${INC_PATH_SUFFIXES_LIST}) list(APPEND FFTW_REQUIRED_VARS "FFTW_${component}_INCLUDE_DIR") if(FFTW_${component}_LIB) set(FFTW_${component}_INC_FOUND 1) endif() else() set(FFTW_${component}_INC_FOUND 1) endif() if(FFTW_${component}_LIB_FOUND AND FFTW_${component}_INC_FOUND) set(FFTW_${component}_FOUND 1) else() set(FFTW_${component}_FOUND 0) endif() endmacro() macro(_mangle_names) endmacro() # ------------------------------------------------------------------------------ # Make sure that all components are in capitals set(_tmp_component_list) foreach(_comp ${FFTW_FIND_COMPONENTS}) string(TOUPPER ${_comp} _comp) list(APPEND _tmp_component_list ${_comp}) endforeach() set(FFTW_FIND_COMPONENTS ${_tmp_component_list}) set(_tmp_component_list) # ------------------------------------------------------------------------------ ## FFTW can be compiled and subsequently linked against ## various data types. ## There is a single set of include files, and then muttiple libraries, ## One for each type. I.e. libfftw.a-->double, libfftwf.a-->float if(NOT FFTW_FIND_COMPONENTS OR FFTW_FIND_COMPONENTS STREQUAL "ALL") set(FFTW_FIND_ALL_COMPONENTS 1) set(FFTW_FIND_COMPONENTS "FFTW;FFTW_MT;FFTWF;FFTWF_MT") endif() if(NOT DEFINED FFTW_FIND_VERSION_MAJOR) set(FFTW_FIND_VERSION_MAJOR 3) endif() if(FFTW_FIND_VERSION_MAJOR EQUAL 2) set(_fftw_suffix "") elseif(FFTW_FIND_VERSION_MAJOR EQUAL 3) set(_fftw_suffix "3") else() message(FATAL_ERROR "Unsupported version number for FFTW") endif() # ------------------------------------------------------------------------------ foreach(_comp ${FFTW_FIND_COMPONENTS}) if(_comp STREQUAL "FFTW") _find_library_with_header(${_comp} fftw${_fftw_suffix} fftw${_fftw_suffix}.h) elseif(_comp STREQUAL "FFTW_MT") _find_library_with_header(${_comp} fftw${_fftw_suffix}_threads fftw${_fftw_suffix}.h) elseif(_comp STREQUAL "FFTWF" AND FFTW_FIND_VERSION_MAJOR GREATER 2) _find_library_with_header(${_comp} fftw${_fftw_suffix}f fftw${_fftw_suffix}.h) elseif(_comp STREQUAL "FFTWF_MT" AND FFTW_FIND_VERSION_MAJOR GREATER 2) _find_library_with_header(${_comp} fftw${_fftw_suffix}f_threads fftw${_fftw_suffix}.h) else() message(FATAL_ERROR "Unknown component (looked for FFTW ${FFTW_FIND_VERSION_MAJOR}): ${_comp}") endif() mark_as_advanced( FFTW_${_comp}_LIB FFTW_${_comp}_INCLUDE_DIR) endforeach() # ============================================================================== include(FindPackageHandleStandardArgs) find_package_handle_standard_args(FFTW FOUND_VAR FFTW_FOUND REQUIRED_VARS ${FFTW_REQUIRED_VARS} HANDLE_COMPONENTS) # ============================================================================== if(FFTW_FOUND) # Inspired by FindBoost.cmake foreach(_comp ${FFTW_FIND_COMPONENTS}) if(NOT TARGET FFTW::${_comp} AND FFTW_${_comp}_FOUND) get_filename_component(LIB_EXT "${FFTW_${_comp}_LIB}" EXT) if(LIB_EXT STREQUAL ".a" OR LIB_EXT STREQUAL ".lib") set(LIB_TYPE STATIC) else() set(LIB_TYPE SHARED) endif() add_library(FFTW::${_comp} ${LIB_TYPE} IMPORTED GLOBAL) set_target_properties(FFTW::${_comp} PROPERTIES IMPORTED_LOCATION "${FFTW_${_comp}_LIB}" INTERFACE_INCLUDE_DIRECTORIES "${FFTW_${_comp}_INCLUDE_DIR}") endif() if(FFTW_${_comp}_FOUND) set(APPEND FFTW_INCLUDE_DIRS "${FFTW_${_comp}_INCLUDE_DIR}") set(APPEND FFTW_LIBRARIES "${FFTW_${_comp}_LIB}") endif() endforeach() # ---------------------------------------------------------------------------- if(NOT FFTW_FIND_QUIETLY) message(STATUS "Found FFTW and defined the following imported targets:") foreach(_comp ${FFTW_FIND_COMPONENTS}) message(STATUS " - FFTW::${_comp}:") message(STATUS " + include: ${FFTW_${_comp}_INCLUDE_DIR}") message(STATUS " + library: ${FFTW_${_comp}_LIB}") endforeach() endif() endif() # ============================================================================== mark_as_advanced( FFTW_FOUND FFTW_INCLUDE_DIRS FFTW_LIBRARIES ) bart-0.5.00/cmake/FindLAPACKE.cmake000066400000000000000000000176101353046746100164650ustar00rootroot00000000000000#.rst: # FindLAPACKE # ------------- # # Find LAPACKE include dirs and libraries # # Use this module by invoking find_package with the form:: # # find_package(LAPACKE # [REQUIRED] # Fail with error if LAPACKE is not found # [COMPONENTS ...] # List of libraries to look for # ) # # Valid names for COMPONENTS libraries are:: # # ALL - Find all libraries # LAPACKE_H - Find the lapacke.h header file # LAPACKE - Find a LAPACKE library # LAPACK - Find a LAPACK library # CBLAS - Find a CBLAS library # BLAS - Find a BLAS library # # Not specifying COMPONENTS is identical to choosing ALL # # This module defines:: # # LAPACKE_FOUND - True if headers and requested libraries were found # LAPACKE_INCLUDE_DIRS - LAPACKE include directories # LAPACKE_LIBRARIES - LAPACKE component libraries to be linked # # # This module reads hints about search locations from variables # (either CMake variables or environment variables):: # # LAPACKE_ROOT - Preferred installation prefix for LAPACKE # LAPACKE_DIR - Preferred installation prefix for LAPACKE # # # The following :prop_tgt:`IMPORTED` targets are also defined:: # # LAPACKE::LAPACKE - Imported target for the LAPACKE library # LAPACKE::LAPACK - Imported target for the LAPACK library # LAPACKE::CBLAS - Imported target for the CBLAS library # LAPACKE::BLAS - Imported target for the BLAS library # # ============================================================================== # Copyright 2018 Damien Nguyen # # Distributed under the OSI-approved BSD License (the "License") # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ============================================================================== set(LAPACKE_SEARCH_PATHS ${LAPACKE_ROOT} $ENV{LAPACKE_ROOT} ${LAPACKE_DIR} $ENV{LAPACKE_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /usr /usr/local/ /usr/local/opt # homebrew on mac /opt /opt/local /opt/LAPACKE ) set(LIB_PATH_SUFFIXES lib64 lib lib/x86_64-linux-gnu lib32 ) set(INC_PATH_SUFFIXES include include/lapack include/lapacke/ lapack/include lapacke/include ) if(APPLE) list(APPEND LIB_PATH_SUFFIXES lapack/lib openblas/lib) elseif(WIN32) list(APPEND LAPACKE_SEARCH_PATHS "C:/Program Files (x86)/LAPACK") list(APPEND LAPACKE_SEARCH_PATHS "C:/Program Files/LAPACK") endif() # ============================================================================== # Prepare some helper variables set(LAPACKE_INCLUDE_DIRS) set(LAPACKE_LIBRARIES) set(LAPACKE_REQUIRED_VARS) set(LAPACKE_FIND_ALL_COMPONENTS 0) # ============================================================================== macro(_find_library_with_header component incname) find_library(LAPACKE_${component}_LIB NAMES ${ARGN} NAMES_PER_DIR PATHS ${LAPACKE_SEARCH_PATHS} PATH_SUFFIXES ${LIB_PATH_SUFFIXES}) if(LAPACKE_${component}_LIB) set(LAPACKE_${component}_LIB_FOUND 1) endif() list(APPEND LAPACKE_REQUIRED_VARS "LAPACKE_${component}_LIB") # If necessary, look for the header file as well if(NOT "${incname}" STREQUAL "") find_path(LAPACKE_${component}_INCLUDE_DIR NAMES ${incname} PATHS ${LAPACKE_SEARCH_PATHS} PATH_SUFFIXES ${INC_PATH_SUFFIXES}) list(APPEND LAPACKE_REQUIRED_VARS "LAPACKE_${component}_INCLUDE_DIR") if(LAPACKE_${component}_LIB) set(LAPACKE_${component}_INC_FOUND 1) endif() else() set(LAPACKE_${component}_INC_FOUND 1) endif() if(LAPACKE_${component}_LIB_FOUND AND LAPACKE_${component}_INC_FOUND) set(LAPACKE_${component}_FOUND 1) else() set(LAPACKE_${component}_FOUND 0) endif() endmacro() # ------------------------------------------------------------------------------ if(NOT LAPACKE_FIND_COMPONENTS OR LAPACKE_FIND_COMPONENTS STREQUAL "ALL") set(LAPACKE_FIND_ALL_COMPONENTS 1) set(LAPACKE_FIND_COMPONENTS "LAPACKE;LAPACK;CBLAS;BLAS") endif(NOT LAPACKE_FIND_COMPONENTS OR LAPACKE_FIND_COMPONENTS STREQUAL "ALL") # Make sure that all components are in capitals set(_tmp_component_list) foreach(_comp ${LAPACKE_FIND_COMPONENTS}) string(TOUPPER ${_comp} _comp) list(APPEND _tmp_component_list ${_comp}) endforeach() set(LAPACKE_FIND_COMPONENTS ${_tmp_component_list}) set(_tmp_component_list) foreach(_comp ${LAPACKE_FIND_COMPONENTS}) if(_comp STREQUAL "LAPACKE") _find_library_with_header(${_comp} lapacke.h lapacke liblapacke) elseif(_comp STREQUAL "LAPACKE_H") find_path(LAPACKE_${_comp}_INCLUDE_DIR NAMES lapacke.h PATHS ${LAPACKE_SEARCH_PATHS} PATH_SUFFIXES include lapack/include) list(APPEND LAPACKE_REQUIRED_VARS "LAPACKE_${_comp}_INCLUDE_DIR") if(LAPACKE_${_comp}_LIB) set(LAPACKE_${_comp}_INC_FOUND 1) endif() elseif(_comp STREQUAL "LAPACK") _find_library_with_header(${_comp} "" lapack liblapack) elseif(_comp STREQUAL "CBLAS") _find_library_with_header(${_comp} cblas.h cblas libcblas) elseif(_comp STREQUAL "BLAS") _find_library_with_header(${_comp} "" blas blas) else() message(FATAL_ERROR "Unknown component: ${_comp}") endif() mark_as_advanced( LAPACKE_${_comp}_LIB LAPACKE_${_comp}_INCLUDE_DIR) endforeach() # ============================================================================== include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LAPACKE FOUND_VAR LAPACKE_FOUND REQUIRED_VARS ${LAPACKE_REQUIRED_VARS} HANDLE_COMPONENTS) # ============================================================================== if(LAPACKE_FOUND) foreach(_comp ${LAPACKE_FIND_COMPONENTS}) list(APPEND LAPACKE_INCLUDE_DIRS ${LAPACKE_${_comp}_INCLUDE_DIR}) list(APPEND LAPACKE_LIBRARIES ${LAPACKE_${_comp}_LIB}) endforeach() if("${CMAKE_C_COMPILER_ID}" MATCHES ".*Clang.*" OR "${CMAKE_C_COMPILER_ID}" MATCHES ".*GNU.*" OR "${CMAKE_C_COMPILER_ID}" MATCHES ".*Intel.*" ) #NOT MSVC set(MATH_LIB "m") list(APPEND LAPACKE_LIBRARIES m) endif() if(NOT "${LAPACKE_INCLUDE_DIRS}" STREQUAL "") list(REMOVE_DUPLICATES LAPACKE_INCLUDE_DIRS) endif() # ---------------------------------------------------------------------------- # Inspired by FindBoost.cmake foreach(_comp ${LAPACKE_FIND_COMPONENTS}) if(NOT TARGET LAPACKE::${_comp} AND LAPACKE_${_comp}_FOUND) get_filename_component(LIB_EXT "${LAPACKE_${_comp}_LIB}" EXT) if(LIB_EXT STREQUAL ".a" OR LIB_EXT STREQUAL ".lib") set(LIB_TYPE STATIC) else() set(LIB_TYPE SHARED) endif() add_library(LAPACKE::${_comp} ${LIB_TYPE} IMPORTED GLOBAL) if(LAPACKE_INCLUDE_DIRS) set_target_properties(LAPACKE::${_comp} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LAPACKE_INCLUDE_DIRS}") endif() if(EXISTS "${LAPACKE_${_comp}_LIB}") set_target_properties(LAPACKE::${_comp} PROPERTIES IMPORTED_LOCATION "${LAPACKE_${_comp}_LIB}") endif() set_target_properties(LAPACKE::${_comp} PROPERTIES INTERFACE_LINK_LIBRARIES "${MATH_LIB}") endif() endforeach() # ---------------------------------------------------------------------------- if(NOT LAPACKE_FIND_QUIETLY) message(STATUS "Found LAPACKE and defined the following imported targets:") foreach(_comp ${LAPACKE_FIND_COMPONENTS}) message(STATUS " - LAPACKE::${_comp}:") message(STATUS " + include: ${LAPACKE_INCLUDE_DIRS}") message(STATUS " + library: ${LAPACKE_${_comp}_LIB}") message(STATUS " + dependencies: ${MATH_LIB}") endforeach() endif() endif() # ============================================================================== mark_as_advanced( LAPACKE_FOUND LAPACKE_INCLUDE_DIRS LAPACKE_LIBRARIES ) bart-0.5.00/cmake/FindMatlab.cmake000066400000000000000000000212501353046746100166200ustar00rootroot00000000000000# - this module looks for Matlab # Defines: # MATLAB_INCLUDE_DIR: include path for mex.h, engine.h # MATLAB_LIBRARIES: required libraries: libmex, etc # MATLAB_MEX_LIBRARY: path to libmex.lib # MATLAB_MX_LIBRARY: path to libmx.lib # MATLAB_MAT_LIBRARY: path to libmat.lib # added # MATLAB_ENG_LIBRARY: path to libeng.lib # MATLAB_ROOT: path to Matlab's root directory # This file is part of Gerardus # # This is a derivative work of file FindMatlab.cmake released with # CMake v2.8, because the original seems to be a bit outdated and # doesn't work with my Windows XP and Visual Studio 10 install # # (Note that the original file does work for Ubuntu Natty) # # Author: Ramon Casero , Tom Doel # Version: 0.2.3 # $Rev$ # $Date$ # # The original file was copied from an Ubuntu Linux install # /usr/share/cmake-2.8/Modules/FindMatlab.cmake #============================================================================= # Copyright 2005-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) set(MATLAB_FOUND 0) if(WIN32) # Search for a version of Matlab available, starting from the most modern one to older versions foreach(MATVER "7.14" "7.11" "7.10" "7.9" "7.8" "7.7" "7.6" "7.5" "7.4") if((NOT DEFINED MATLAB_ROOT) OR ("${MATLAB_ROOT}" STREQUAL "") OR ("${MATLAB_ROOT}" STREQUAL "/registry")) get_filename_component(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${MATVER};MATLABROOT]" ABSOLUTE) set(MATLAB_VERSION ${MATVER}) endif() endforeach() # Directory name depending on whether the Windows architecture is 32 # bit or 64 bit set(CMAKE_SIZEOF_VOID_P 8) # Note: For some wierd reason this variable is undefined in my system... if(CMAKE_SIZEOF_VOID_P MATCHES "4") set(WINDIR "win32") elseif(CMAKE_SIZEOF_VOID_P MATCHES "8") set(WINDIR "win64") else() message(FATAL_ERROR "CMAKE_SIZEOF_VOID_P (${CMAKE_SIZEOF_VOID_P}) doesn't indicate a valid platform") endif() # Folder where the MEX libraries are, depending of the Windows compiler if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6") set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc60") elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio 7") # Assume people are generally using Visual Studio 7.1, # if using 7.0 need to link to: ../extern/lib/${WINDIR}/microsoft/msvc70 set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc71") # set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc70") elseif(${CMAKE_GENERATOR} MATCHES "Borland") # Assume people are generally using Borland 5.4, # if using 7.0 need to link to: ../extern/lib/${WINDIR}/microsoft/msvc70 set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc54") # set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc50") # set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc51") elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio*") # If the compiler is Visual Studio, but not any of the specific # versions above, we try our luck with the microsoft directory set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/") else() message(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}") endif() else() if((NOT DEFINED MATLAB_ROOT) OR ("${MATLAB_ROOT}" STREQUAL "")) if(APPLE) # If this is a Mac and the attempts to find MATLAB_ROOT have so far failed, # we look in the applications folder # Search for a version of Matlab available, starting from the most modern one to older versions foreach(MATVER "R2017b" "R2017a" "R2016b" "R2016a" "R2015b" "R2015a" "R2014b" "R2014a" "R2013b" "R2013a" "R2012b" "R2012a" "R2011b" "R2011a" "R2010b" "R2010a" "R2009b" "R2009a" "R2008b") if(EXISTS /Applications/MATLAB_${MATVER}.app) set(MATLAB_ROOT /Applications/MATLAB_${MATVER}.app) endif() endforeach() endif() ## Search for matlab find_program(MATLAB_EXEC NAMES matlab HINTS ENV PATH PATHS ${MATLAB_ROOT}/bin DOC "The command line matlab program" ) get_filename_component(MATLAB_EXEC "${MATLAB_EXEC}" REALPATH) get_filename_component(MATLAB_EXEC_DIR "${MATLAB_EXEC}" DIRECTORY) if(NOT MATLAB_ROOT) get_filename_component(MATLAB_ROOT "${MATLAB_EXEC_DIR}" DIRECTORY) endif() if(NOT MATLAB_EXEC) message(FATAL_ERROR "Matlab not found") endif() endif() # Check if this is a Mac if(APPLE) set(LIBRARY_EXTENSION dylib) else() set(LIBRARY_EXTENSION so) endif() find_program( MATLAB_MEX_PATH mex HINTS ENV PATH PATHS ${MATLAB_ROOT}/bin DOC "The mex program path" ) find_program( MATLAB_MEXEXT_PATH mexext HINTS ENV PATH PATHS ${MATLAB_ROOT}/bin DOC "The mexext program path" ) #Get default mex extentension execute_process( COMMAND ${MATLAB_MEXEXT_PATH} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE MATLAB_MEX_EXT ) ## Remove the mex prefix to find the platform name if(APPLE) string(REPLACE "mex" "" MATLAB_PLATFORM_DIR ${MATLAB_MEX_EXT}) else() string(REPLACE "mex" "glnx" MATLAB_PLATFORM_DIR ${MATLAB_MEX_EXT}) endif() set(MATLAB_LIBRARIES_DIR ${MATLAB_ROOT}/bin/${MATLAB_PLATFORM_DIR}) endif() # Get path to the MEX libraries find_library(MATLAB_MEX_LIBRARY NAMES libmex.${LIBRARY_EXTENSION} PATHS ${MATLAB_LIBRARIES_DIR} NO_DEFAULT_PATH ) find_library(MATLAB_MX_LIBRARY NAMES libmx.${LIBRARY_EXTENSION} PATHS ${MATLAB_LIBRARIES_DIR} NO_DEFAULT_PATH ) find_library(MATLAB_MAT_LIBRARY NAMES libmat.${LIBRARY_EXTENSION} PATHS ${MATLAB_LIBRARIES_DIR} NO_DEFAULT_PATH ) find_library(MATLAB_ENG_LIBRARY NAMES libeng.${LIBRARY_EXTENSION} PATHS ${MATLAB_LIBRARIES_DIR} NO_DEFAULT_PATH ) # Get path to the include directory find_path(MATLAB_INCLUDE_DIR NAMES "mex.h" PATHS "${MATLAB_ROOT}/extern/include" ) # This is common to UNIX and Win32: set(MATLAB_LIBRARIES ${MATLAB_MX_LIBRARY} ${MATLAB_MEX_LIBRARY} ${MATLAB_MAT_LIBRARY} ${MATLAB_ENG_LIBRARY} ) if(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES) set(MATLAB_FOUND 1) endif() mark_as_advanced( MATLAB_LIBRARIES MATLAB_MX_LIBRARY MATLAB_MEX_LIBRARY MATLAB_MAT_LIBRARY MATLAB_ENG_LIBRARY MATLAB_INCLUDE_DIR MATLAB_FOUND MATLAB_ROOT MATLAB_MEX_PATH MATLAB_MEXEXT_PATH MATLAB_MEX_EXT ) ##################### ##################### # Provide a macro to build the mex files from # within CMake ##################### # BuildMex.cmake # \author Kent Williams norman-k-williams@uiowa.edu # \author Hans J. Johnson hans-johnson@uiowa.edu include(CMakeParseArguments) include_directories(${MATLAB_INCLUDE_DIR}) # # BuildMex -- arguments # MEXNAME = root of mex library name # TARGETDIR = location for the mex library files to be created # SOURCE = list of source files # LIBRARIES = libraries needed to link mex library macro(BuildMex) set(oneValueArgs MEXNAME TARGETDIR) set(multiValueArgs SOURCE LIBRARIES) cmake_parse_arguments(BuildMex "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) # message("MEXNAME=${BuildMex_MEXNAME} SOURCE=${BuildMex_SOURCE} LIBRARIES=${BuildMex_LIBRARIES}") set_source_files_properties(${BuildMex_SOURCE} COMPILE_DEFINITIONS -DMATLAB_MEX_FILE ) add_library(${BuildMex_MEXNAME} SHARED ${BuildMex_SOURCE}) set_target_properties(${BuildMex_MEXNAME} PROPERTIES SUFFIX ".${MATLAB_MEX_EXT}" PREFIX "" RUNTIME_OUTPUT_DIRECTORY "${BuildMex_TARGETDIR}" ARCHIVE_OUTPUT_DIRECTORY "${BuildMex_TARGETDIR}" LIBRARY_OUTPUT_DIRECTORY "${BuildMex_TARGETDIR}" ) target_link_libraries(${BuildMex_MEXNAME} ${BuildMex_LIBRARIES} ${MATLAB_MEX_LIBRARY} ${MATLAB_MX_LIBRARY} ${MATLAB_ENG_LIBRARY}) endmacro(BuildMex) bart-0.5.00/cmake/FindOpenBLAS.cmake000066400000000000000000000177321353046746100167750ustar00rootroot00000000000000#.rst: # FindOpenBLAS # ------------- # # Find OpenBLAS include dirs and libraries # # Use this module by invoking find_package with the form:: # # find_package(OpenBLAS # [REQUIRED] # Fail with error if OpenBLAS is not found # ) # # # This module defines:: # # OpenBLAS_FOUND - set to true if the library is found # OpenBLAS_INCLUDE_DIRS - list of required include directories # OpenBLAS_LIBRARIES - list of libraries to be linked # OpenBLAS_HAS_PARALLEL_LIBRARIES - determine if there are parallel libraries compiled # OpenBLAS_PARALLEL_LIBRARIES - list of libraries for parallel implementations # OpenBLAS_VERSION_MAJOR - major version number # OpenBLAS_VERSION_MINOR - minor version number # OpenBLAS_VERSION_PATCH - patch version number # OpenBLAS_VERSION_STRING - version number as a string (ex: "0.2.18") # # # This module reads hints about search locations from variables # (either CMake variables or environment variables):: # # OpenBLAS_ROOT - Preferred installation prefix for OpenBLAS # OpenBLAS_DIR - (for compatibility purposes) # # # OpenBLAS::OpenBLAS - Imported target for the OpenBLAS library # # ============================================================================== # Copyright 2016 Hans J. Johnson # Copyright 2018 Damien Nguyen # # Distributed under the OSI-approved BSD License (the "License") # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ============================================================================== set(OpenBLAS_SEARCH_PATHS ${OpenBLAS_ROOT} $ENV{OpenBLAS_ROOT} ${OpenBLAS_DIR} $ENV{OpenBLAS_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /usr /usr/local/ /usr/local/opt # homebrew on mac /opt /opt/local /opt/OpenBLAS ) set(PATH_SUFFIXES_LIST lib64 lib lib/x86_64-linux-gnu lib32 ) if(APPLE) list(APPEND PATH_SUFFIXES_LIST openblas/lib) endif() # ============================================================================== # Prepare some helper variables set(OpenBLAS_INCLUDE_DIRS) set(OpenBLAS_LIBRARIES) set(OpenBLAS_HAS_PARALLEL_LIBRARIES FALSE) # ============================================================================== ## First try to find OpenBLAS with NO_MODULE, ## As of 20160706 version 0.2.18 there is limited cmake support for OpenBLAS ## that is not as complete as this version, if found, use it ## to identify the OpenBLAS_VERSION_STRING and improve searching. find_package(OpenBLAS NO_MODULE QUIET) if(OpenBLAS_VERSION) set(OpenBLAS_VERSION_STRING ${OpenBLAS_VERSION}) unset(OpenBLAS_VERSION) # Use cmake conventional naming endif() # ============================================================================== ### First search for headers find_path(OpenBLAS_CBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${OpenBLAS_SEARCH_PATHS} PATH_SUFFIXES include include/openblas) # ============================================================================== ### Second, search for libraries find_library(OpenBLAS_LIB NAMES openblas PATHS ${OpenBLAS_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST}) if(OpenBLAS_LIB) get_filename_component(OpenBLAS_LIB_DIR i${OpenBLAS_LIB} DIRECTORY) include(CheckLibraryExists) check_library_exists(${OpenBLAS_LIB} LAPACKE_cheev "" HAVE_LAPACKE_CHEEV) check_library_exists(${OpenBLAS_LIB} LAPACKE_zgesdd "" HAVE_LAPACKE_ZGESDD) if(NOT HAVE_LAPACKE_CHEEV OR NOT HAVE_LAPACKE_ZGESDD) message(WARNING "OpenBLAS has no LAPACKE symbols. Attempting to look for a LAPACKE library") find_package(LAPACKE QUIET COMPONENTS LAPACKE) if(LAPACKE_FOUND) message(STATUS "Found LAPACKE: ${LAPACKE_LIBRARIES}") list(APPEND OpenBLAS_LIBRARIES ${LAPACKE_LIBRARIES}) else() message(WARNING "Unable to find a LAPACKE library. Consider configuring CMake with BART_NO_LAPACKE=ON") endif() else() # Make sure we find lapacke.h find_package(LAPACKE QUIET COMPONENTS LAPACKE_H) endif() endif() ## Find the named parallel version of openblas set(OpenBLAS_SEARCH_VERSIONS ${OpenBLAS_VERSION_STRING} 0.3.2 0.3.1 0.3.0 0.2.19 0.2.18 0.2.17 0.2.16) list(REMOVE_DUPLICATES OpenBLAS_SEARCH_VERSIONS) foreach(checkVersion ${OpenBLAS_SEARCH_VERSIONS}) find_library(OpenBLAS_PARALLEL_LIB NAMES openblasp-r${checkVersion} PATHS ${OpenBLAS_LIB_DIR} ${OpenBLAS_SEARCH_PATHS} PATH_SUFFIXES ${PATH_SUFFIXES_LIST} ) if(EXISTS ${OpenBLAS_PARALLEL_LIB}) if(NOT OpenBLAS_VERSION_STRING) set(OpenBLAS_VERSION_STRING ${checkVersion}) endif() set(OpenBLAS_HAS_PARALLEL_LIBRARIES ON) break() endif() endforeach() # WARNING: We may not be able to determine the version of some OpenBLAS set(OpenBLAS_VERSION_MAJOR 0) set(OpenBLAS_VERSION_MINOR 0) set(OpenBLAS_VERSION_PATCH 0) if(OpenBLAS_VERSION_STRING) string(REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\1" OpenBLAS_VERSION_MAJOR "${OpenBLAS_VERSION_STRING}") string(REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\2" OpenBLAS_VERSION_MINOR "${OpenBLAS_VERSION_STRING}") string(REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\3" OpenBLAS_VERSION_PATCH "${OpenBLAS_VERSION_STRING}") endif() # ============================================================================== # Checks 'REQUIRED', 'QUIET' and versions. include(FindPackageHandleStandardArgs) find_package_handle_standard_args(OpenBLAS FOUND_VAR OpenBLAS_FOUND REQUIRED_VARS OpenBLAS_CBLAS_INCLUDE_DIR OpenBLAS_LIB LAPACKE_INCLUDE_DIRS VERSION_VAR OpenBLAS_VERSION_STRING ) # ------------------------------------------------------------------------------ if (OpenBLAS_FOUND) list(APPEND OpenBLAS_INCLUDE_DIRS ${OpenBLAS_CBLAS_INCLUDE_DIR} ${LAPACKE_INCLUDE_DIRS}) list(REMOVE_DUPLICATES OpenBLAS_INCLUDE_DIRS) if("${CMAKE_C_COMPILER_ID}" MATCHES ".*Clang.*" OR "${CMAKE_C_COMPILER_ID}" MATCHES ".*GNU.*" OR "${CMAKE_C_COMPILER_ID}" MATCHES ".*Intel.*" ) #NOT MSVC set(MATH_LIB m) endif() list(APPEND OpenBLAS_LIBRARIES ${OpenBLAS_LIB} ${MATH_LIB}) if(OpenBLAS_HAS_PARALLEL_LIBRARIES) list(APPEND OpenBLAS_PARALLEL_LIBRARIES ${OpenBLAS_PARALLEL_LIB}) endif() # ---------------------------------------------------------------------------- if(NOT TARGET OpenBLAS::OpenBLAS) get_filename_component(LIB_EXT "${LAPACKE_${UPPERCOMPONENT}_LIB}" EXT) if(LIB_EXT STREQUAL ".a" OR LIB_EXT STREQUAL ".lib") set(LIB_TYPE STATIC) else() set(LIB_TYPE SHARED) endif() add_library(OpenBLAS::OpenBLAS ${LIB_TYPE} IMPORTED GLOBAL) set(_tmp_dep_libs "${MATH_LIB};${LAPACKE_LIBRARIES}") list(REMOVE_DUPLICATES _tmp_dep_libs) set_target_properties(OpenBLAS::OpenBLAS PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OpenBLAS_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${_tmp_dep_libs}") if(OpenBLAS_HAS_PARALLEL_LIBRARIES) set_target_properties(OpenBLAS::OpenBLAS PROPERTIES IMPORTED_LOCATION "${OpenBLAS_PARALLEL_LIB}") else() set_target_properties(OpenBLAS::OpenBLAS PROPERTIES IMPORTED_LOCATION "${OpenBLAS_LIB}") endif() endif() # ---------------------------------------------------------------------------- if(NOT OpenBLAS_FIND_QUIETLY) get_target_property(_lib OpenBLAS::OpenBLAS IMPORTED_LOCATION) get_target_property(_dep_libs OpenBLAS::OpenBLAS INTERFACE_LINK_LIBRARIES) message(STATUS "Found OpenBLAS and defined the OpenBLAS::OpenBLAS imported target:") message(STATUS " - include: ${OpenBLAS_INCLUDE_DIRS}") message(STATUS " - library: ${_lib}") message(STATUS " - dependencies: ${_dep_libs}") endif() endif() # ============================================================================== mark_as_advanced( OpenBLAS_FOUND OpenBLAS_INCLUDE_DIRS OpenBLAS_LIBRARIES OpenBLAS_HAS_PARALLEL_LIBRARIES OpenBLAS_PARALLEL_LIBRARIES OpenBLAS_VERSION_MAJOR OpenBLAS_VERSION_MINOR OpenBLAS_VERSION_PATCH OpenBLAS_VERSION_STRING ) bart-0.5.00/cmake/FindPythonSupport.cmake000066400000000000000000001360351353046746100203060ustar00rootroot00000000000000# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. # # This file is a "template" file used by various FindPython modules. # if(CMAKE_VERSION VERSION_GREATER 3.6.99) cmake_policy (VERSION 3.7) else() set(_policy_list_37 66) set(_policy_list_34 64 65) set(_policy_list_33 57 58 59 60 61 62 63) set(_policy_list_32 55 56) set(_policy_list_31 51 52 53 54) set(_policy_list_30 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 41 42 43 44 45 46 47 48 49 50) cmake_policy (VERSION ${CMAKE_VERSION}) set(_policy_list) foreach(_minor RANGE 6) if(_minor LESS ${CMAKE_MINOR_VERSION} OR _minor EQUAL ${CMAKE_MINOR_VERSION}) list(APPEND _policy_list ${_policy_list_3${_minor}}) endif() endforeach() foreach(_policy ${_policy_list}) if(POLICY ${_policy}) cmake_policy(SET ${_policy} NEW) endif() endforeach() endif() if(CMAKE_VERSION VERSION_GREATER 3.3.99) set(_names_per_dir NAMES_PER_DIR) else() set(_names_per_dir) endif() # # Initial configuration # if (NOT DEFINED _PYTHON_PREFIX) message (FATAL_ERROR "FindPython: INTERNAL ERROR") endif() if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) message (FATAL_ERROR "FindPython: INTERNAL ERROR") endif() if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) set(_${_PYTHON_PREFIX}_VERSIONS 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) else() message (FATAL_ERROR "FindPython: INTERNAL ERROR") endif() # # helper commands # macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) if (${_PYTHON_PREFIX}_FIND_REQUIRED) message (FATAL_ERROR "${_PYTHON_MSG}") else() if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) message(STATUS "${_PYTHON_MSG}") endif () endif() set (${_PYTHON_PREFIX}_FOUND FALSE) string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) return() endmacro() function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) set (_PYTHON_FRAMEWORK_PATHS) foreach (_PYTHON_FRAMEWORK IN LISTS Python_FRAMEWORKS) list (APPEND _PYTHON_FRAMEWORK_PATHS "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") endforeach() set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) endfunction() function (_PYTHON_VALIDATE_INTERPRETER) if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) return() endif() if (${_PYTHON_PREFIX}_EXECUTABLE MATCHES "python${CMAKE_EXECUTABLE_SUFFIX}$") # executable found do not have version in name # ensure major version is OK execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(str(sys.version_info[0]))" RESULT_VARIABLE result OUTPUT_VARIABLE version ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) # interpreter not usable or has wrong major version set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) return() endif() endif() list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development" _index) if (CMAKE_SIZEOF_VOID_P AND _index GREATER -1 AND NOT CMAKE_CROSSCOMPILING) # In this case, interpreter must have same architecture as environment execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" RESULT_VARIABLE result OUTPUT_VARIABLE size ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) # interpreter not usable or has wrong architecture set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) return() endif() endif() endfunction() function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") # look at runtime part on systems supporting it if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) # MSYS has a special syntax for runtime libraries if (CMAKE_SYSTEM_NAME MATCHES "MSYS") list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") endif() find_library (${ARGV}) endif() endfunction() function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) unset (_PYTHON_DIRS) set (_PYTHON_LIBS ${ARGV}) list (REMOVE_AT _PYTHON_LIBS 0) foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) if (${_PYTHON_LIB}) get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") endif() endforeach() if (_PYTHON_DIRS) list (REMOVE_DUPLICATES _PYTHON_DIRS) endif() set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) endfunction() # If major version is specified, it must be the same as internal major version if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") endif() # handle components if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) endif() foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) endforeach() unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) # Set versions to search ## default: search any version set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) else() unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) # add all compatible versions foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION) list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) endif() endforeach() endif() endif() # Anaconda distribution: define which architectures can be used if (CMAKE_SIZEOF_VOID_P) # In this case, search only for 64bit or 32bit math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) else() # architecture unknown, search for both 64bit and 32bit set (_${_PYTHON_PREFIX}_ARCH 64) set (_${_PYTHON_PREFIX}_ARCH2 32) endif() # IronPython support if (CMAKE_SIZEOF_VOID_P) # In this case, search only for 64bit or 32bit math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) else() # architecture unknown, search for natural interpreter set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) endif() # Apple frameworks handling include (CMakeFindFrameworks) cmake_find_frameworks (Python) # Save CMAKE_FIND_FRAMEWORK if (DEFINED CMAKE_FIND_FRAMEWORK) set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) else() unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) endif() # To avoid picking up the system elements pre-maturely. set (CMAKE_FIND_FRAMEWORK LAST) unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) unset (_${_PYTHON_PREFIX}_CACHED_VARS) # first step, search for the interpreter list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" _index) if (_index GREATER -1) if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) endif() set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) # look-up for various versions and locations foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) # try using HINTS find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_VERSION} ${_names_per_dir} HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} PATH_SUFFIXES bin NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) # try using registry if (WIN32) find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_VERSION} python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} ${_names_per_dir} HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] PATH_SUFFIXES bin NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) endif() # try in standard paths find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_VERSION}) _python_validate_interpreter () if (${_PYTHON_PREFIX}_EXECUTABLE) break() endif() endforeach() # try more generic names if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES bin) _python_validate_interpreter () endif() # retrieve exact version of executable found if (${_PYTHON_PREFIX}_EXECUTABLE) execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (NOT _${_PYTHON_PREFIX}_RESULT) string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) else() # Interpreter is not usable set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) unset (${_PYTHON_PREFIX}_VERSION) endif() endif() if (${_PYTHON_PREFIX}_EXECUTABLE AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) # Use interpreter version for future searches to ensure consistency set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) endif() if (${_PYTHON_PREFIX}_Interpreter_FOUND) # retrieve interpreter identity execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) if (NOT _${_PYTHON_PREFIX}_RESULT) if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") else() string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") # try to get a more precise ID execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT ERROR_QUIET) if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") endif() endif() endif() else() set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) endif() else() unset (${_PYTHON_PREFIX}_INTERPRETER_ID) endif() # retrieve various package installation directories execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS ERROR_QUIET) if (NOT _${_PYTHON_PREFIX}_RESULT) list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) else() unset (${_PYTHON_PREFIX}_STDLIB) unset (${_PYTHON_PREFIX}_STDARCH) unset (${_PYTHON_PREFIX}_SITELIB) unset (${_PYTHON_PREFIX}_SITEARCH) endif() mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) endif() # second step, search for compiler (IronPython) list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Compiler" _index) if (_index GREATER -1) if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) endif() # IronPython specific artifacts # If IronPython interpreter is found, use its path unset (_${_PYTHON_PREFIX}_IRON_ROOT) if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) endif() # try using root dir and registry foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) find_program (${_PYTHON_PREFIX}_COMPILER NAMES ipyc HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) if (${_PYTHON_PREFIX}_COMPILER) break() endif() endforeach() # try in standard paths find_program (${_PYTHON_PREFIX}_COMPILER NAMES ipyc) if (${_PYTHON_PREFIX}_COMPILER) # retrieve python environment version from compiler set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" OUTPUT_QUIET ERROR_QUIET) execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION ERROR_QUIET) if (NOT _${_PYTHON_PREFIX}_RESULT) string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) # set public version information set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) endif() else() # compiler not usable set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) endif() file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") endif() if (${_PYTHON_PREFIX}_COMPILER) if (${_PYTHON_PREFIX}_Interpreter_FOUND) # Compiler must be compatible with interpreter if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) endif() elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) # Use compiler version for future searches to ensure consistency set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) endif() endif() if (${_PYTHON_PREFIX}_Compiler_FOUND) set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) else() unset (${_PYTHON_PREFIX}_COMPILER_ID) endif() mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) endif() # third step, search for the development artifacts ## Development environment is not compatible with IronPython interpreter list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development" _index) if (_index GREATER -1 AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY ${_PYTHON_PREFIX}_INCLUDE_DIR) list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG ${_PYTHON_PREFIX}_INCLUDE_DIR) endif() # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) else() list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) endif() else() endif() # if python interpreter is found, use its location and version to ensure consistency # between interpreter and development environment unset (_${_PYTHON_PREFIX}_PREFIX) if (${_PYTHON_PREFIX}_Interpreter_FOUND) execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (_${_PYTHON_PREFIX}_RESULT) unset (_${_PYTHON_PREFIX}_PREFIX) endif() endif() set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) # try to use pythonX.Y-config tool set (_${_PYTHON_PREFIX}_CONFIG_NAMES) if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") endif() list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") find_program (_${_PYTHON_PREFIX}_CONFIG NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} HINTS ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES bin) unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) if (NOT _${_PYTHON_PREFIX}_CONFIG) continue() endif() # retrieve root install directory execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (_${_PYTHON_PREFIX}_RESULT) # python-config is not usable unset (_${_PYTHON_PREFIX}_CONFIG CACHE) continue() endif() set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) # retrieve library execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (NOT _${_PYTHON_PREFIX}_RESULT) # retrieve library directory string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) # retrieve library name string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} PATH_SUFFIXES lib NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) # retrieve runtime library if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} PATH_SUFFIXES bin NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) endif() endif() # retrieve include directory execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (NOT _${_PYTHON_PREFIX}_RESULT) # retrieve include directory string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) find_path (${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) endif() if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) break() endif() endforeach() # Rely on HINTS and standard paths if config tool failed to locate artifacts if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) # search first in known locations find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} python${_${_PYTHON_PREFIX}_VERSION}mu python${_${_PYTHON_PREFIX}_VERSION}m python${_${_PYTHON_PREFIX}_VERSION}u python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} lib/python${_${_PYTHON_PREFIX}_VERSION}/config NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) # search in all default paths find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} python${_${_PYTHON_PREFIX}_VERSION}mu python${_${_PYTHON_PREFIX}_VERSION}m python${_${_PYTHON_PREFIX}_VERSION}u python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} lib/python${_${_PYTHON_PREFIX}_VERSION}/config) # retrieve runtime library if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} python${_${_PYTHON_PREFIX}_VERSION}mu python${_${_PYTHON_PREFIX}_VERSION}m python${_${_PYTHON_PREFIX}_VERSION}u python${_${_PYTHON_PREFIX}_VERSION} NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES bin) endif() if (WIN32) # search for debug library if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) # use library location as a hint get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} NO_DEFAULT_PATH) else() # search first in known locations find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR HINTS ${_${_PYTHON_PREFIX}_HINTS} PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES lib libs NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) # search in all default paths find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR PATH_SUFFIXES lib libs) endif() if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES bin) endif() endif() # Don't search for include dir until library location is known if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) if (${_${_PYTHON_PREFIX}_LIB}) # Use the library's install prefix as a hint if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") else() # assume library is in a directory under root get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") endif() endif() endforeach() list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) find_path (${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu include/python${_${_PYTHON_PREFIX}_VERSION}m include/python${_${_PYTHON_PREFIX}_VERSION}u include/python${_${_PYTHON_PREFIX}_VERSION} include NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) endif() if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) break() endif() endforeach() # search header file in standard locations find_path (${_PYTHON_PREFIX}_INCLUDE_DIR NAMES Python.h) endif() if (${_PYTHON_PREFIX}_INCLUDE_DIR) # retrieve version from header file file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) # set public version information set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) endif() endif() # define public variables include (SelectLibraryConfigurations) select_library_configurations (${_PYTHON_PREFIX}) if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") else() set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") endif() _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) if (UNIX) if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) endif() else() _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) endif() set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG ${_PYTHON_PREFIX}_INCLUDE_DIR) if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) # development environment must be compatible with interpreter/compiler if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) set (${_PYTHON_PREFIX}_Development_FOUND TRUE) endif() elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) set (${_PYTHON_PREFIX}_Development_FOUND TRUE) endif() endif() # Restore the original find library ordering if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) endif() endif() # final validation if (${_PYTHON_PREFIX}_VERSION_MAJOR AND NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") endif() include (FindPackageHandleStandardArgs) find_package_handle_standard_args (${_PYTHON_PREFIX} REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} VERSION_VAR ${_PYTHON_PREFIX}_VERSION HANDLE_COMPONENTS) # Create imported targets and helper functions list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" _index) if (_index GREATER -1 AND ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) set_property (TARGET ${_PYTHON_PREFIX}::Interpreter PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") endif() list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Compiler" _index) if (_index GREATER -1 AND ${_PYTHON_PREFIX}_Compiler_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) set_property (TARGET ${_PYTHON_PREFIX}::Compiler PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") endif() list (FIND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development" _index) if (_index GREATER -1 AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) else() set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) endif() add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) # System manage shared libraries in two parts: import and runtime if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) set_target_properties (${_PYTHON_PREFIX}::Python PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") set_target_properties (${_PYTHON_PREFIX}::Python PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") else() set_target_properties (${_PYTHON_PREFIX}::Python PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") endif() else() if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) set_target_properties (${_PYTHON_PREFIX}::Python PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") set_target_properties (${_PYTHON_PREFIX}::Python PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") else() set_target_properties (${_PYTHON_PREFIX}::Python PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") endif() endif() if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") # extend link information with dependent libraries execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (NOT _${_PYTHON_PREFIX}_RESULT) string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") # remove elements relative to python library itself list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") endforeach() set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) endif() endif() # # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) # It is used to build modules for python. # function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE" "" "") unset (type) if (NOT (PYTHON_ADD_LIBRARY_STATIC OR PYTHON_ADD_LIBRARY_SHARED OR PYTHON_ADD_LIBRARY_MODULE)) set (type MODULE) endif() add_library (${name} ${type} ${ARGN}) target_link_libraries (${name} PRIVATE ${prefix}::Python) # customize library name to follow module name rules get_property (type TARGET ${name} PROPERTY TYPE) if (type STREQUAL "MODULE_LIBRARY") set_property (TARGET ${name} PROPERTY PREFIX "") if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") endif() endif() endfunction() endif() # final clean-up # Restore CMAKE_FIND_FRAMEWORK if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) else() unset (CMAKE_FIND_FRAMEWORK) endif() unset (_${_PYTHON_PREFIX}_CONFIG CACHE) bart-0.5.00/cmake/FindlibFlame.cmake000066400000000000000000000116271353046746100171420ustar00rootroot00000000000000#.rst: # FindlibFlame # ------------- # # Find libFlame include dirs and libraries # # Use this module by invoking find_package with the form:: # # find_package(libFlame # [REQUIRED] # Fail with error if libFlame is not found # ) # # This module defines:: # # libFlame_FOUND - True if headers and requested libraries were found # libFlame_INCLUDE_DIRS - libFlame include directories # libFlame_LIBRARIES - libFlame component libraries to be linked # # # This module reads hints about search locations from variables # (either CMake variables or environment variables):: # # libFlame_ROOT - Preferred installation prefix # libFlame_DIR - Preferred installation prefix # # # The following :prop_tgt:`IMPORTED` targets are also defined:: # # libFlame::libFlame - Target for specific component dependency # (shared or static library) # # ============================================================================== # Copyright 2018 Damien Nguyen # # Distributed under the OSI-approved BSD License (the "License") # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # ============================================================================== set(libFlame_SEARCH_PATHS ${libFlame_ROOT} $ENV{libFlame_ROOT} ${libFlame_DIR} $ENV{libFlame_DIR} $ENV{CMAKE_PREFIX_PATH} ${CMAKE_PREFIX_PATH} /usr /usr/local/ /usr/local/amd /opt /opt/amd /opt/local ) find_library(libFlame_LIBRARY NAMES flame PATHS ${libFlame_SEARCH_PATHS} PATH_SUFFIXES lib lib32 lib64 libflame/lib ) if(libFLame_LIBRARY) get_filename_component(libFlame_ROOT_HINT ${libFlame_LIBRARY} PATH) # for CMake > 2.8.11 we should really use DIRECTORY get_filename_component(libFlame_ROOT_HINT ${libFlame_ROOT_HINT} PATH) endif() find_path(libFlame_INCLUDE_DIR NAMES FLAME.h flame.h HINTS ${libFlame_ROOT_HINT} PATHS ${libFlame_SEARCH_PATHS} PATH_SUFFIXES include libflame/include ) set(libFlame_LAPACKE_COMPONENTS cblas) # ============================================================================== if(libFLame_LIBRARY) include(CheckLibraryExists) check_library_exists(${libFlame_LIBRARY} zgesdd_ "" HAVE_ZGESDD) check_library_exists(${libFlame_LIBRARY} zgelss_ "" HAVE_ZGELSS) if(HAVE_ZGESDD AND HAVE_ZGELSS) set(HAVE_LAPACK_INTERFACE 1) else() set(HAVE_LAPACK_INTERFACE 0) endif() set(LAPACK_LIB_VAR "") if(NOT HAVE_LAPACK_INTERFACE) message(STATUS "libFlame has no LAPACK interface, looking for a LAPACK library") list(APPEND libFlame_LAPACKE_COMPONENTS lapack) endif() # ---------------------------------------------------------------------------- find_package(LAPACKE QUIET REQUIRED COMPONENTS ${libFlame_LAPACKE_COMPONENTS}) endif() # ============================================================================== include(FindPackageHandleStandardArgs) find_package_handle_standard_args(libFlame FOUND_VAR libFlame_FOUND REQUIRED_VARS libFlame_INCLUDE_DIR libFlame_LIBRARY LAPACKE_FOUND LAPACKE_LIBRARIES LAPACKE_INCLUDE_DIRS ) # ============================================================================== if(libFlame_FOUND) set(libFlame_INCLUDE_DIRS) list(APPEND libFlame_INCLUDE_DIRS ${libFlame_INCLUDE_DIR} ${LAPACKE_INCLUDE_DIRS}) list(REMOVE_DUPLICATES libFlame_INCLUDE_DIRS) set(libFlame_LIBRARIES) list(APPEND libFlame_LIBRARIES ${libFlame_LIBRARY} ${LAPACKE_LIBRARIES}) # ---------------------------------------------------------------------------- if(NOT TARGET libFlame::libFlame) get_filename_component(LIB_EXT "${libFlame_LIBRARY}" EXT) if(LIB_EXT STREQUAL ".a" OR LIB_EXT STREQUAL ".lib") set(LIB_TYPE STATIC) else() set(LIB_TYPE SHARED) endif() add_library(libFlame::libFlame ${LIB_TYPE} IMPORTED GLOBAL) set_target_properties(libFlame::libFlame PROPERTIES IMPORTED_LOCATION "${libFlame_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${libFlame_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${LAPACKE_LIBRARIES}" ) endif() # ---------------------------------------------------------------------------- ## For debugging if(NOT libFlame_FIND_QUIETLY) get_target_property(_dep_libs libFlame::libFlame INTERFACE_LINK_LIBRARIES) message(STATUS "Found libFlame and defined the libFlame::libFlame imported target:") message(STATUS " - include: ${libFlame_INCLUDE_DIR}") message(STATUS " - library: ${libFlame_LIBRARY}") message(STATUS " - dependencies: ${_dep_libs}") endif() endif() # ============================================================================== mark_as_advanced( libFlame_LIBRARY libFlame_INCLUDE_DIR libFlame_CBLAS_INCLUDE_DIR ) # ============================================================================== bart-0.5.00/cmake/bart_configure_add_header.cmake000066400000000000000000000011421353046746100217260ustar00rootroot00000000000000set(_required_vars INFILE OUTFILE PREFIX) foreach(_var ${_required_vars}) if(NOT DEFINED "${_var}") message(FATAL_ERROR "Variable ${_var} is undefined!") endif() endforeach() if(NOT EXISTS "${INFILE}") message(FATAL_ERROR "\n\nMissing input file '${INFILE}' for generating '${OUTFILE}'\n\n") endif() # ============================================================================== file(READ "${INFILE}" _file_content) set(_prefix_string) foreach(_line ${PREFIX}) set(_prefix_string "${_prefix_string}\n${_line}") endforeach() file(WRITE "${OUTFILE}" "${_prefix_string}\n\n\n${_file_content}") bart-0.5.00/cmake/bart_install.cmake000066400000000000000000000107551353046746100173050ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen include(GNUInstallDirs) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/BART) set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}/bart) # ============================================================================== # Install the documentation file(GLOB DOCS "${PROJECT_SOURCE_DIR}/doc/*.txt") list(APPEND ${PROJECT_SOURCE_DIR}/README) install(FILES ${DOCS} DESTINATION ${CMAKE_INSTALL_DOCDIR}) # Install the header files install(DIRECTORY ${PROJECT_SOURCE_DIR}/src/ DESTINATION ${INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" PATTERN "*.hh") # Separate if users want minimalistic installation install(FILES ${PROJECT_SOURCE_DIR}/src/bart_embed_api.h DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT for_embedding) # Install all of the targets (except bartmain) set(BART_TARGET_LIST bart bartsupport mat2cfl pyBART) foreach(target ${BART_TARGET_LIST}) if(TARGET ${target}) install(TARGETS ${target} EXPORT bart-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() endforeach() # Install bartmain separately to allow installation only of bartmain install(TARGETS bartmain EXPORT bart-targets-for-embedding RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT for_embedding ) # ============================================================================== # Now take care of exporting all the information for inclusion in other CMake # projects # Write a CMake file with information about the version of BART being compiled include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/BARTConfigVersion.cmake VERSION "${BART_VERSION_MAJOR}.${BART_VERSION_MINOR}.${BART_VERSION_PATCH}" COMPATIBILITY SameMajorVersion) # Write a CMake config file configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/BARTConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BARTConfig.cmake INSTALL_DESTINATION ${INSTALL_CONFIGDIR}) #Install the config, configversion and custom find modules install(FILES ${CMAKE_CURRENT_LIST_DIR}/BARTFindBLASlib.cmake ${CMAKE_CURRENT_LIST_DIR}/FindATLAS.cmake ${CMAKE_CURRENT_LIST_DIR}/FindCUDAlibs.cmake ${CMAKE_CURRENT_LIST_DIR}/FindFFTW.cmake ${CMAKE_CURRENT_LIST_DIR}/FindLAPACKE.cmake ${CMAKE_CURRENT_LIST_DIR}/FindlibFlame.cmake ${CMAKE_CURRENT_LIST_DIR}/FindMatlab.cmake ${CMAKE_CURRENT_LIST_DIR}/FindOpenBLAS.cmake ${CMAKE_CURRENT_BINARY_DIR}/BARTConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/BARTConfigVersion.cmake DESTINATION ${INSTALL_CONFIGDIR} COMPONENT for_embedding ) if(CMAKE_VERSION VERSION_LESS 3.11) install(FILES ${CMAKE_CURRENT_LIST_DIR}/FindBOpenMP.cmake DESTINATION ${INSTALL_CONFIGDIR} COMPONENT for_embedding ) endif() # Write a CMake file with all the targets information # (not for installing, but for external project to import targets from the # current build tree) if(CMAKE_VERSION VERSION_LESS 3.0) export(TARGETS bartsupport bart ${BART_MATLAB_TGT} ${BART_pyBART_TGT} FILE ${CMAKE_CURRENT_BINARY_DIR}/BARTTargets.cmake NAMESPACE BART::) export(TARGETS bartmain FILE ${CMAKE_CURRENT_BINARY_DIR}/BARTTargetsForEmbedding.cmake NAMESPACE BART::) else() export(EXPORT bart-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/BARTTargets.cmake NAMESPACE BART::) export(EXPORT bart-targets-for-embedding FILE ${CMAKE_CURRENT_BINARY_DIR}/BARTTargetsForEmbedding.cmake NAMESPACE BART::) endif() # Install the general CMake target file install(EXPORT bart-targets FILE BARTTargets.cmake NAMESPACE BART:: DESTINATION ${INSTALL_CONFIGDIR} ) # Install the CMake target file for embedding install(EXPORT bart-targets-for-embedding FILE BARTTargetsForEmbedding.cmake NAMESPACE BART:: DESTINATION ${INSTALL_CONFIGDIR} COMPONENT for_embedding ) # Register BART in user package directory export(PACKAGE BART) # ============================================================================== # Add a few convenience targets add_custom_target(install_for_embedding COMMAND ${CMAKE_COMMAND} -DCOMPONENT=for_embedding -P ${CMAKE_BINARY_DIR}/cmake_install.cmake) add_custom_target (uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake) bart-0.5.00/cmake/bart_macros.cmake000066400000000000000000000076221353046746100171220ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen # Extract the version number based on version.txt or similar formatted file macro(get_version_from_file filename) message(STATUS "Getting version info from ${filename}") file(READ ${filename} _version_string) string(STRIP ${_version_string} _version_string) string(SUBSTRING ${_version_string} 1 -1 _version_string) string(REGEX MATCHALL "[0-9]+" _version_list ${_version_string}) list(GET _version_list 0 _version_major) list(GET _version_list 1 _version_minor) list(GET _version_list 2 _version_patch) endmacro() # ------------------------------------------------------------------------------ # BART Makefile depends on a GCC flag to add an extra include directive from # the command line: -include src/main.h, which essentially results in # '#include "src/main.h" being added at the top of each file being compiled. # However, since this is not portable (GCC/Clang use -include, MSVC /FI, Intel # does not suppport it), we use a slightly different approach here. # Instead, we simply create a copy of the file with the added line at the top # at *build* time. We also make sure that if the original file should be # modified, CMake would automatically re-generate it. macro(configure_file_add_header INFILE PREFIX) set(_script "${CMAKE_CURRENT_LIST_DIR}/cmake/bart_configure_add_header.cmake") set(_output_folder ${CMAKE_CURRENT_BINARY_DIR}/CombinedCode) get_filename_component(_name ${INFILE} NAME) set(OUTFILE "${_output_folder}/${_name}") # We need to add a protected ';' after each element here as it will be # interpreted when CMake prepares the command line arguments below # In addition, we also need to escape quotes set(_prefix) foreach(_line ${PREFIX}) string(REPLACE "\"" "\\\"" _line ${_line}) list(APPEND _prefix "\"${_line}\"\;") endforeach() add_custom_command(OUTPUT ${OUTFILE} COMMAND ${CMAKE_COMMAND} -E make_directory "${_output_folder}" COMMAND ${CMAKE_COMMAND} -DINFILE="${INFILE}" -DOUTFILE="${OUTFILE}" -DPREFIX="${_prefix}" -P "${_script}" DEPENDS ${INFILE} ) endmacro() # ------------------------------------------------------------------------------ include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) # Find a compatible compiler flag from a series of list of possible flags # For each list of whitespace separated compiler flags passed in argument, this # function will append or save the compatible flags in ${var_prefix}_c and # ${var_prefix}_cxx (if C++ is enabled) macro(check_for_compiler_flags var_prefix) set(_c_opts) set(_cxx_opts) foreach(_flag_list ${ARGN}) separate_arguments(_flag_list) foreach(_flag ${_flag_list}) # Drop the first character (most likely either '-' or '/') string(SUBSTRING ${_flag} 1 -1 _flag_name) string(REGEX REPLACE "[-:/]" "_" _flag_name ${_flag_name}) check_c_compiler_flag(${_flag} c_compiler_has_${_flag_name}) if(c_compiler_has_${_flag_name}) list(APPEND _c_opts ${_flag}) break() endif() endforeach() if(CMAKE_CXX_COMPILER_LOADED) foreach(_flag ${_flag_list}) # Drop the first character (most likely either '-' or '/') string(SUBSTRING ${_flag} 1 -1 _flag_name) string(REGEX REPLACE "[-:/]" "_" _flag_name ${_flag_name}) check_cxx_compiler_flag(${_flag} cxx_compiler_has_${_flag_name}) if(cxx_compiler_has_${_flag_name}) list(APPEND _cxx_opts ${_flag}) break() endif() endforeach() endif() endforeach() if(DEFINED ${var_prefix}_c) list(APPEND ${var_prefix}_c ${_c_opts}) else() set(${var_prefix}_c ${_c_opts}) endif() if(DEFINED ${var_prefix}_cxx) list(APPEND ${var_prefix}_cxx ${_cxx_opts}) else() set(${var_prefix}_cxx ${_cxx_opts}) endif() endmacro() bart-0.5.00/cmake/bart_options.cmake000066400000000000000000000340561353046746100173320ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen option(BART_DISABLE_PNG "Disable the use of the PNG library" OFF) option(BART_ENABLE_MEM_CFL "Enable the use of in-memory CFL files" OFF) option(BART_FPIC "Compile using position-independent code" OFF) option(BART_FFTWTHREADS "Enable multi-threaded FFTW libraries" ON) option(BART_GENERATE_DOC "Automatically generate documentation after building BART" OFF) option(BART_LOCAL_FFTW "Use a modified version of FFTW where all functions are prefixed with local_ (useful for static FFTW linking)" OFF) option(BART_MEMONLY_CFL "Use only in-memory CFL files" OFF) option(BART_MATLAB "Specify if the optional matlab programs should be built" OFF) option(BART_NO_LAPACKE "Compile without LAPACKE installed on the system" OFF) option(BART_REDEFINE_PRINTF_FOR_TRACE "Replace debug_print* functions with macros for better log tracing (e.g. with external loggers)" OFF) ##- TODO option(BART_SLINK "Provide SLINK support" OFF) find_package(ISMRMRD QUIET CONFIG) ## if you can find ISMRMRD by default, then default configuration is ON option(BART_ISMRMRD "Use external ISMRMRD package for reading/writing" ${ISMRMRD_FOUND}) # ------------------------------------------------------------------------------ option(BART_CREATE_PYTHON_MODULE "Compile the pyBART Python module" OFF) option(BART_PYTHON_FORCE_27 "Force BART to use Python 2.7" OFF) # ------------------------------------------------------------------------------ include(CMakeDependentOption) option(BART_LOG_BACKEND "Enable delegating all outputs to external logging backend" OFF) cmake_dependent_option(BART_LOG_SIEMENS_BACKEND "Use the Siemens logging backend" OFF "BART_LOG_BACKEND" OFF) cmake_dependent_option(BART_LOG_ORCHESTRA_BACKEND "Use the Orchestra logging backend" OFF "BART_LOG_BACKEND" OFF) cmake_dependent_option(BART_LOG_GADGETRON_BACKEND "Use the Gadgetron logging backend" OFF "BART_LOG_BACKEND" OFF) # ------------------------------------------------------------------------------ option(BART_SA "Turn on static analysis for compiling and linking BART" OFF) cmake_dependent_option(BART_SA_CPPCHECK "Run cppcheck on each file" OFF "BART_SA" OFF) cmake_dependent_option(BART_SA_CLANG_TIDY "Run clang-tidy on each file" OFF "BART_SA" OFF) cmake_dependent_option(BART_SA_IWYU "Run include-what-you-use on each file" OFF "BART_SA" OFF) cmake_dependent_option(BART_SA_LWYU "Run link-what-you-use at the linking stage" OFF "BART_SA" OFF) # ------------------------------------------------------------------------------ option(USE_CUDA "Provide support for CUDA processing" OFF) if(CMAKE_VERSION VERSION_GREATER 3.9.99) cmake_dependent_option(USE_CUDA_NATIVE "Use native CMake support for CUDA (instead of relying on the FindCUDA module)" ON "USE_CUDA" OFF) endif() option(USE_OPENMP "Enable OpenMP support" ON) # ============================================================================== if(BART_CREATE_PYTHON_MODULE) message(STATUS "Generating the pyBART Python module") if(NOT BART_ENABLE_MEM_CFL) message(STATUS " - Setting BART_ENABLE_MEM_CFL = ON") set(BART_ENABLE_MEM_CFL ON CACHE BOOL "Enable the use of in-memory CFL files" FORCE) endif() if(NOT BART_FPIC) message(STATUS " - Setting BART_FPIC = ON") set(BART_FPIC ON CACHE BOOL "Compile using position-independent code" FORCE) endif() endif() if(BART_PYTHON_FORCE_27) set(_python_version 2.7) else() set(_python_version) endif() # -------------------------------------- if(BART_ENABLE_MEM_CFL OR USE_CUDA OR BART_LOG_BACKEND) enable_language(CXX) endif() # -------------------------------------- if(BART_DISABLE_PNG) set(PNG_TGT "") else() find_package(PNG REQUIRED) if(CMAKE_VERSION VERSION_LESS 3.5) add_library(PNG::PNG SHARED IMPORTED GLOBAL) set_target_properties(PNG::PNG PROPERTIES IMPORTED_LOCATION "${PNG_LIBRARY}" INTERFACE_DEFINITIONS "${PNG_DEFINITIONS}" INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${PNG_LIBRARIES}" ) endif() set(PNG_TGT "PNG::PNG") endif() # -------------------------------------- if(BART_MEMONLY_CFL) message(STATUS "Forcing BART to use only in-memory CFLs") if(NOT BART_ENABLE_MEM_CFL) message(STATUS " - Setting BART_ENABLE_MEM_CFL = ON") set(BART_ENABLE_MEM_CFL ON CACHE BOOL "Enable the use of in-memory CFL files") endif() add_definitions(-DMEMONLY_CFL) endif(BART_MEMONLY_CFL) if(BART_ENABLE_MEM_CFL) message(STATUS "Using in-memory CFL files") add_definitions(-DUSE_MEM_CFL) endif(BART_ENABLE_MEM_CFL) # -------------------------------------- if(BART_FPIC) message(STATUS "ENABLED compilation with -fPIC") set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() # -------------------------------------- if(BART_GENERATE_DOC) message(STATUS "Automatically generating documentation after building BART") endif() # -------------------------------------- if(BART_LOCAL_FFTW) # manually add the pthread library in case one is using static fftw libraries... set(CMAKE_THREAD_PREFER_PTHREAD ON) find_package(Threads REQUIRED) add_definitions(-DUSE_LOCAL_FFTW) add_library(FFTW::FFTWF STATIC IMPORTED GLOBAL) set_target_properties(FFTW::FFTWF PROPERTIES INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/src" IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/lib/libfftw3f.a") add_library(FFTW::FFTWF_MT STATIC IMPORTED GLOBAL) set_target_properties(FFTW::FFTWF_MT PROPERTIES INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/src" INTERFACE_LINK_LIBRARIES "Threads::Threads" IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/lib/libfftw3f_threads.a") else() find_package(FFTW 3 REQUIRED COMPONENTS FFTWF FFTWF_MT) endif() set(FFTW_TGT "FFTW::FFTWF;FFTW::FFTWF_MT") if(BART_FFTWTHREADS) add_definitions(-DFFTWTHREADS) else() # remove the threaded library when not using threads list(REMOVE_ITEM FFTW_TGT "FFTW::FFTWF_MT") endif() # -------------------------------------- if(BART_NO_LAPACKE) set(ATLAS_NO_LAPACKE ON) set(OpenBLAS_NO_LAPACKE ON) set(BLAS_NO_LAPACKE ON) add_definitions(-DNOLAPACKE) include_directories(${CMAKE_CURRENT_LIST_DIR}/src/lapacke) message(STATUS "Compiling with NOLAPACKE") endif() # -------------------------------------- if(BART_REDEFINE_PRINTF_FOR_TRACE) add_definitions(-DREDEFINE_PRINTF_FOR_TRACE) message(STATUS "Redefining debug_print* functions as macros for better log tracing") endif(BART_REDEFINE_PRINTF_FOR_TRACE) # -------------------------------------- if(BART_ISMRMRD) find_package(ISMRMRD REQUIRED) endif() # ============================================================================== if(BART_LOG_SIEMENS_BACKEND) message(STATUS "Delegating all outputs to the Siemens logging backend") endif(BART_LOG_SIEMENS_BACKEND) if(BART_LOG_ORCHESTRA_BACKEND) message(STATUS "Delegating all outputs to the Orchestra logging backend") endif(BART_LOG_ORCHESTRA_BACKEND) if(BART_LOG_GADGETRON_BACKEND) message(STATUS "Delegating all outputs to the Gadgetron logging backend") endif(BART_LOG_GADGETRON_BACKEND) # ============================================================================== if(BART_SA) if(BART_SA_CPPCHECK) find_program(_cppcheck NAMES cppcheck DOC "cppcheck executable path" ) mark_as_advanced(_cppcheck) if(NOT _cppcheck) message(WARNING "Unable to find the path to the cppcheck executable") else() set(BART_SA_CPPCHECK_C_ARGS "" CACHE STRING "Arguments to pass to cppcheck for C code") set(BART_SA_CPPCHECK_CXX_ARGS "-std=c++11" CACHE STRING "Arguments to pass to cppcheck for C++ code") set(CMAKE_C_CPPCHECK "${_cppcheck};${BART_SA_CPPCHECK_C_ARGS}") set(CMAKE_CXX_CPPCHECK "${_cppcheck};${BART_SA_CPPCHECK_CXX_ARGS}") endif() endif() if(BART_SA_CLANG_TIDY) find_program(_clang_tidy NAMES clang-tidy DOC "clang-tidy executable path" ) mark_as_advanced(_clang_tidy) if(NOT _clang_tidy) message(WARNING "Unable to find the path to the clang-tidy executable") else() set(BART_SA_CLANG_TIDY_C_ARGS "-checks=*,-cppcoreguidelines-*,-hicpp-*" CACHE STRING "Arguments to pass to clang-tidy for C code") set(BART_SA_CLANG_TIDY_CXX_ARGS "-checks=*" CACHE STRING "Arguments to pass to clang-tidy for C++ code") set(CMAKE_C_CLANG_TIDY "${_clang_tidy};${BART_SA_CLANG_TIDY_C_ARGS}") set(CMAKE_CXX_CLANG_TIDY "${_clang_tidy};${BART_SA_CLANG_TIDY_CXX_ARGS}") endif() endif() if(BART_SA_IWYU) find_program(_iwyu NAMES iwyu include-what-you-use DOC "include-what-you-use executable path" ) mark_as_advanced(_iwyu) if(NOT _iwyu) message(WARNING "Unable to find the path to the _iwyu executable") else() set(BART_SA_IWYU_C_ARGS "" CACHE STRING "Arguments to pass to include-what-you-use for C code") set(BART_SA_IWYU_CXX_ARGS "" CACHE STRING "Arguments to pass to include-what-you-use for C++ code") set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${_iwyu};${BART_SA_IWYU_C_ARGS}") set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${_iwyu};${BART_SA_IWYU_CXX_ARGS}") endif() endif() if(BART_SA_LWYU) set(CMAKE_LINK_WHAT_YOU_USE TRUE) endif() endif() # ============================================================================== if(USE_CUDA) # Actually, CMake >= 3.8 supports CUDA natively, but at least on my machine, # the command line generated by CMake 3.8.X & 3.9.X contains # -isystem /usr/include which causes the compilation to fail. # So... only use the new feature for CMake >= 3.10 if(CMAKE_VERSION VERSION_LESS 3.10) set(BART_USE_NATIVE_CUDA FALSE) else() if(USE_CUDA_NATIVE) set(BART_USE_NATIVE_CUDA TRUE) else() set(BART_USE_NATIVE_CUDA FALSE) endif() endif() if(NOT BART_USE_NATIVE_CUDA) find_package(CUDA REQUIRED) add_definitions(-DUSE_CUDA) CUDA_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/src) # set(CUDA_NVCC_FLAGS "-DUSE_CUDA;-Xcompiler;-fPIC;-Xcompiler;-fopenmp;-O3;-arch=sm_20;-m64;-ccbin ${CMAKE_C_COMPILER}") set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-std=c++11;-DUSE_CUDA;-Xcompiler;-fPIC;-O3;${GPUARCH_FLAGS};-ccbin ${CMAKE_C_COMPILER}") macro(bart_add_object_library target_name) add_library(${target_name} OBJECT ${ARGN}) target_compile_definitions(${target_name} PRIVATE -DUSE_CUDA -Derror=bart_error__) target_include_directories(${target_name} PRIVATE "${CUDA_INCLUDE_DIRS}") endmacro() macro(bart_add_executable target_name) set(CUDA_LINK_LIBRARIES_KEYWORD PUBLIC) # was introduced in CMake 3.9 CUDA_ADD_EXECUTABLE(${target_name} ${ARGN}) target_compile_definitions(${target_name} PRIVATE -DUSE_CUDA -Derror=bart_error__) target_link_libraries(${target_name} PUBLIC ${CUDA_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES}) endmacro() macro(bart_add_library target_name) set(CUDA_LINK_LIBRARIES_KEYWORD PUBLIC) # was introduced in CMake 3.9 CUDA_ADD_LIBRARY(${target_name} ${ARGN}) target_compile_definitions(${target_name} PRIVATE -DUSE_CUDA -Derror=bart_error__) target_link_libraries(${target_name} PUBLIC ${CUDA_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES}) endmacro() else() enable_language(CUDA) set (CMAKE_CUDA_STANDARD 11) set (CMAKE_CUDA_STANDARD_REQUIRED ON) find_package(CUDAlibs REQUIRED COMPONENTS CUBLAS CUFFT) macro(bart_add_object_library target_name) add_library(${target_name} OBJECT ${ARGN}) target_compile_definitions(${target_name} PRIVATE -DUSE_CUDA -Derror=bart_error__) target_include_directories(${target_name} PRIVATE "${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}") endmacro() macro(bart_add_executable target_name) add_executable(${target_name} ${ARGN}) target_compile_definitions(${target_name} PRIVATE -DUSE_CUDA -Derror=bart_error__) target_link_libraries(${target_name} PUBLIC "CUDAlibs::CUBLAS;CUDAlibs::CUFFT") set_target_properties(${target_name} PROPERTIES CUDA_SEPARABLE_COMPILATION ON) endmacro() macro(bart_add_library target_name) add_library(${target_name} ${ARGN}) target_compile_definitions(${target_name} PRIVATE -DUSE_CUDA -Derror=bart_error__) target_link_libraries(${target_name} PUBLIC "CUDAlibs::CUBLAS;CUDAlibs::CUFFT") set_target_properties(${target_name} PROPERTIES CUDA_SEPARABLE_COMPILATION ON) endmacro() endif() else() # NOT USE_CUDA macro(bart_add_object_library target_name) add_library(${target_name} OBJECT ${ARGN}) target_compile_definitions(${target_name} PRIVATE -Derror=bart_error__) endmacro() macro(bart_add_executable target_name) add_executable(${target_name} ${ARGN}) target_compile_definitions(${target_name} PRIVATE -Derror=bart_error__) endmacro() macro(bart_add_library target_name) add_library(${target_name} ${ARGN}) target_compile_definitions(${target_name} PRIVATE -Derror=bart_error__) endmacro() endif() # ------------------------------------------------------------------------------ if(USE_OPENMP) if(CMAKE_VERSION VERSION_LESS 3.11) # Actually CMake 3.9 should be enough for OpenMP::OpenMP support, # however, until CMake 3.11 we might get problems with the # INTERFACE_COMPILE_OPTIONS property if we are compiling with # CMake's native CUDA compilation find_package(BOpenMP REQUIRED) # BOpenMP is FindOpenMP.cmake from 3.12 else() find_package(OpenMP REQUIRED) endif() if(CMAKE_CXX_COMPILER_LOADED) set(OpenMP_TGT "OpenMP::OpenMP_CXX") else() set(OpenMP_TGT "OpenMP::OpenMP_C") endif() if(USE_CUDA) if(CMAKE_CXX_COMPILER_LOADED) set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS}") list(APPEND CUDA_NVCC_FLAGS "-Xcompiler=${OpenMP_CXX_FLAGS}") else(DEFINED CMAKE_CUDA_FLAGS) set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_C_FLAGS}") list(APPEND CUDA_NVCC_FLAGS "-Xcompiler=${OpenMP_C_FLAGS}") endif() endif() endif() # ============================================================================== bart-0.5.00/cmake/bart_python.cmake000066400000000000000000000111621353046746100171510ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen # Interpreter only required to find site-lib directories if(CMAKE_VERSION VERSION_LESS 3.12) find_package(BPython ${_python_version} REQUIRED COMPONENTS Development Interpreter) else() find_package(Python ${_python_version} REQUIRED COMPONENTS Development Interpreter) endif() set(Python_TGT Python::Python) get_target_property(_release_lib ${Python_TGT} IMPORTED_LOCATION_RELEASE) get_target_property(_lib ${Python_TGT} IMPORTED_LOCATION) message(STATUS "Found Python ${Python_VERSION}:") message(STATUS " - Interpreter (${Python_INTERPRETER_ID}): ${Python_EXECUTABLE}") message(STATUS " - Development:") message(STATUS " + include: ${Python_INCLUDE_DIR}") message(STATUS " + site-lib: ${Python_SITELIB}") if(_release_lib) message(STATUS " + library: ${_release_lib}") else() message(STATUS " + library: ${_lib}") endif() # ============================================================================== set(PYBART_PYBIND11_SEARCH_PATHS ${PYBART_PYBIND11_ROOT} $ENV{PYBART_PYBIND11_ROOT} ${PYBART_PYBIND11_DIR} $ENV{PYBART_PYBIND11_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /usr /usr/local/ /opt /opt/local ) set(_pybind11_file pybind11.h) get_filename_component(_python_inc_path ${Python_INCLUDE_DIR} DIRECTORY) get_filename_component(_python_ver_name ${Python_INCLUDE_DIR} NAME) string(REGEX MATCH "python[0-9].[0-9]" _python_ver ${_python_ver_name}) if(UNIX) list(APPEND PYBART_PYBIND11_SEARCH_PATHS "/usr/local/include/${_python_ver}") list(APPEND PYBART_PYBIND11_SEARCH_PATHS "/usr/local/include/${_python_ver}m") endif() find_path(PYBART_PYBIND11_INCLUDE NAMES ${_pybind11_file} HINTS ${Python_SITELIB} ${Python_INCLUDE_DIR} ${Python_EXTRA_INCLUDE_DIR} PATHS ${PYBART_PYBIND11_SEARCH_PATHS} PATH_SUFFIXES pybind11 NO_DEFAULT_PATH ) if(NOT PYBART_PYBIND11_INCLUDE) set(_msg "Unable to find pybind11/${_pybind11_file}. Please set the path to this") set(_msg "${_msg} file on your system to either a system or CMake variable") set(_msg "${_msg} named PYBART_PYBIND11_ROOT or PYBART_PYBIND11_DIR or add the") set(_msg "${_msg} the path to the CMAKE_PREFIX_PATH") message(FATAL_ERROR "${_msg}") endif() # ============================================================================== set(PYBART_NUMPY_SEARCH_PATHS ${PYBART_NUMPY_ROOT} $ENV{PYBART_NUMPY_ROOT} ${PYBART_NUMPY_DIR} $ENV{PYBART_NUMPY_DIR} ${CMAKE_PREFIX_PATH} $ENV{CMAKE_PREFIX_PATH} /usr /usr/local/ /opt /opt/local ) set(_numpy_file arrayobject.h) find_path(PYBART_NUMPY_INCLUDE NAMES ${_numpy_file} HINTS ${Python_SITELIB} PATHS ${PYBART_NUMPY_SEARCH_PATHS} PATH_SUFFIXES numpy/core/include/numpy include/numpy NO_DEFAULT_PATH ) if(NOT PYBART_NUMPY_INCLUDE) set(_msg "Unable to find numpy/${_numpy_file}. Please set the path to this") set(_msg "${_msg} file on your system to either a system or CMake variable") set(_msg "${_msg} named PYBART_NUMPY_ROOT or PYBART_NUMPY_DIR or add the") set(_msg "${_msg} the path to the CMAKE_PREFIX_PATH") message(FATAL_ERROR "${_msg}") endif() # ------------------------------------------------------------------------------ get_filename_component(_numpy_inc_dir ${PYBART_NUMPY_INCLUDE} DIRECTORY) get_filename_component(_pybind11_inc_dir ${PYBART_PYBIND11_INCLUDE} DIRECTORY) get_target_property(_interface_inc_dir ${Python_TGT} INTERFACE_INCLUDE_DIRECTORIES ) list(APPEND _interface_inc_dir ${_numpy_inc_dir}) list(APPEND _interface_inc_dir ${_pybind11_inc_dir}) set_target_properties(${Python_TGT} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_interface_inc_dir}" ) # ============================================================================== set(PYBART_FUNCTION_PROTOTYPE) set(PYBART_COMMANDS_MODULE_METHODS) set(PYBART_COMMANDS_IMPLEMENTATION) foreach(curr_prog ${ALLPROGS}) if(EXISTS "${PROJECT_SOURCE_DIR}/src/${curr_prog}.c") set(PYBART_FUNCTION_PROTOTYPE "${PYBART_FUNCTION_PROTOTYPE}static py::object call_${curr_prog} (const char* cmdline);\n") set(PYBART_COMMANDS_MODULE_METHODS "${PYBART_COMMANDS_MODULE_METHODS} m.def(\"${curr_prog}\", call_${curr_prog}, bart_subcommand_docstring);\n") set(PYBART_COMMANDS_IMPLEMENTATION "${PYBART_COMMANDS_IMPLEMENTATION}py::object call_${curr_prog} (const char* cmdline)\n{\n return call_submain(\"${curr_prog}\", cmdline);\n}\n\n") endif() endforeach() # ============================================================================== bart-0.5.00/cmake/tests_data_generation.cmake.in000066400000000000000000000002151353046746100215700ustar00rootroot00000000000000add_custom_command( OUTPUT @TEST_DATA_OUTPUT@ COMMAND @TEST_DATA_CMD@ DEPENDS @TEST_DATA_DEPS@ WORKING_DIRECTORY @TEST_DATA_DIR@ ) bart-0.5.00/cmake/uninstall.cmake000066400000000000000000000023751353046746100166370ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen # Based on EigenUnintall.cmake set(MANIFEST "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt") if(EXISTS ${MANIFEST}) message(STATUS "============== Uninstalling ===================") file(STRINGS ${MANIFEST} files) foreach(file ${files}) if(EXISTS ${file} OR IS_SYMLINK ${file}) message(STATUS "Removing file: '${file}'") execute_process( COMMAND ${CMAKE_COMMAND} -E remove ${file} OUTPUT_VARIABLE rm_out RESULT_VARIABLE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Failed to remove file: '${file}'.") endif() else() message(STATUS "File '${file}' does not exist.") endif() endforeach(file) message(STATUS "========== Finished Uninstalling ==============") else(EXISTS ${MANIFEST}) message(STATUS "Cannot find install manifest: '${MANIFEST}'") message(STATUS "Probably make install has not been performed") message(STATUS " or install_manifest.txt has been deleted.") endif(EXISTS ${MANIFEST}) bart-0.5.00/doc/000077500000000000000000000000001353046746100133025ustar00rootroot00000000000000bart-0.5.00/doc/applications.txt000066400000000000000000000111401353046746100165260ustar00rootroot00000000000000 (an incomplete list of papers using BART...) Hollingsworth KG, Higgins DM, McCallum M, Ward L, Coombs A, Straub V. Investigating the quantitative fidelity of prospectively undersampled chemical shift imaging in muscular dystrophy with compressed sensing and parallel imaging reconstruction. Magn Reson Med 2014; 72:1610-1619. Zhang T, Cheng JY, Potnick AG, Barth RA, Alley MT, Uecker M, Lustig M, Pauly JM, Vasanawala SS. Fast Pediatric 3D Free Breathing Abdominal Dynamic Contrast Enhanced MRI with a High Spatiotemporal Resolution, J Magn Reson Imaging 2015; 41:460-473. Addy NO, Ingle RR, Wu HH, Hu BS, Nishimura DG. High-resolution variable-density 3D cones coronary MRA. Magn Reson Med 2015; 74:614-621. Cheng JY, Zhang T, Ruangwattanapaisarn N, Alley MT, Uecker M, Pauly JM, Lustig M, Vasanawala SS. Free-Breathing Pediatric MRI with Nonrigid Motion Correction and Acceleration, J Magn Reson Imaging 2015; 42:407-420. Athalye V, Lustig M, Uecker M. Parallel Magnetic Resonance Imaging as Approximation in a Reproducing Kernel Hilbert Space, Inverse Problems 2015; 31:045008. Mann LW, Higgins DM, Peters CN, Cassidy S, Hodson KK, Coombs A, Taylor R, Hollingsworth KG. Accelerating MR Imaging Liver Steatosis Measurement Using Combined Compressed Sensing and Parallel Imaging: A Quantitative Evaluation, Radiology 2016; 278:245-256. Cheng JY, Hanneman K, Zhang T, Alley MT, Lai P, Tamir JI, Uecker M, Pauly JM, Lustig M, Vasanawala SS. Comprehensive Motion-Compensated Highly-Accelerated 4D Flow MRI with Ferumoxytol Enhancement for Pediatric Congenital Heart Disease. J Magn Reson Imaging 2016; 43:1355-1368. Tamir JI, Uecker M, Chen W, Lai P, Aleey MT, Vasanawala SS, Lustig M. T2-Shuffling: Sharp, Multi-Contrast, Volumetric Fast Spin-Echo Imaging. Magn Recon Med 2017; 77:180-195. Uecker M, Lustig M. Estimating Absolute-Phase Maps Using ESPIRiT and Virtual Conjugate Coils. Magn Reson Med 2017; 77:1201-1207. Cheng JY, Zhang T, Alley MT, Uecker M, Lustig M, Pauly JM, Vasanawala SS. Comprehensive Multi-Dimensional MRI for the Simultaneous Assessment of Cardiopulmonary Anatomy and Physiology. Scientific Reports 2017; 7:5330. Bao S, Tamir JI, Young JL, Tariq U, Uecker M, Lai P, Chen W, Lustig M, Vasanawala SS. Fast comprehensive single-sequence four-dimensional pediatric knee MRI with T2 shuffling. J Magn Reson Imaging 2017; 45:1700-1711. Mazzoli V, Schoormans J, Froeling M, Sprengers AM, Coolen BF, Verdonschot N, Strijkers GJ, Nederveen AJ. Accelerated 4D selfâ€gated MRI of tibiofemoral kinematics. NMR in Biomed 2017; 30:e3791. Moghari MH, Uecker M, Roujol S, Sabbagh M, Geva T, Powell AJ. Accelerated Whole-heart Magnetic Resonance Angiography Using a Variable-Density Poisson-Disc Undersampling Pattern and Compressed Sensing Reconstruction. Magn Reson Med 2018; 79:761-769. Peper ES, Strijkers GJ, Gazzola K, Potters WV, Motaal AG, Luirink IK, Hutten BA, Wiegman A, van Ooij P, van den Born B-JH, Nederveen AJ, Coolen BF. Regional assessment of carotid artery pulse wave velocity using compressed sensing accelerated high temporal resolution 2D CINE PC MRI. J Cardiovasc Magn Reson 2018; 20:1-12. Mazzoli V, Gottwald LM, Peper ES, Froeling M, Coolen BF, Verdonschot N, Sprengers AM, van Ooij P, Strijkers GJ, Nederveen AJ. Accelerated 4D phase contrast MRI in skeletal muscles contraction. Magn Reson Med 2018; 80:1799-1811. Rosenzweig S, Holme HCM, Wilke RN, Voit D, Frahm J, Uecker M. Simultaneous Multi-Slice Reconstruction Using Regularized Nonlinear Inversion: SMS-NLINV. Magn Reson Med 2018; 79:2057-2066. Sanders J, Song H, Frank S, Bathala T, Venkatesan A, Anscher M, Tang C, Bruno T, Wei W, Ma J. Parallel imaging compressed sensing for accelerated imaging and improved SNR in MRI-based prostate brachytherapy post-implant dosimetry. Brachytherapy 2018; 17:816-824. Roeloffs V, Rosenzweig S, Holme HCM, Uecker M, Frahm J. Frequency-modulated SSFP with radial sampling and subspace reconstruction: A time-efficient alternative to phase-cycled bSSFP. Magn Reson Med 2019; 81:1566-1579. de Jonge CS, Coolen BF, Peper ES, Motaal AG, Nio CY, Somers I, Strijkers GJ, Stoker J, Nederveen AJ. Evaluation of compressed sensing MRI for accelerated bowel motility imaging. European Radiology Experimental 2019; 3:1-12. Walheim J, Dillinger H, Kozerke. Multipoint 5D flow cardiovascular magnetic resonance - accelerated cardiac- and respiratory-motion resolved mapping of mean and turbulent velocities. J Cardiovasc Magn Reson 2019; 21:42. Wang X, Kohler F, Unterberg-Buchwald C, Lotz J, Frahm J, Uecker M. Model-based myocardial T1 mapping with sparsity constraints using single-shot inversion-recovery radial FLASH. J Cardiovasc Magn Reson 2019; in press. bart-0.5.00/doc/bart.1000066400000000000000000000004661353046746100143220ustar00rootroot00000000000000.TH BART 1 .SH NAME bart - Berkeley Advanced Reconstruction Toolbox .SH SYNOPSIS .B bart .IR command [\fB\-h\fR] ... .SH DESCRIPTION .B bart invokes a command from the Berkeley Advanced Reconstruction Toolbox. .SH AUTHOR BART Developer Team and Contributors. .SH SEE ALSO .B https://mrirecon.github.io/bart/ bart-0.5.00/doc/bitmasks.txt000066400000000000000000000012771353046746100156670ustar00rootroot00000000000000 A bitmask is a binary number where the individual bits are used to indicate something. For example, a bitmask is often used to select a subset of dimensions, e.g. if the FFT should be applited to dimensions 3 and 5 the corresponding bits at position 3 and 5 are set in a bitmask: 876543210 (position of the bit) 000101000b (bitmask as binary number) In decimal this binary number is 40, so the command $ bart fft 40 input output would transform the dimensions 3 and 5 (counting from zero). The 'bitmask' command computes the required bitmask from the set of dimensions: $ bart bitmask 3 5 40 On the command-line both commands can also be combined: $ bart fft 'bart bitmask 3 5' input output bart-0.5.00/doc/building.txt000066400000000000000000000101171353046746100156400ustar00rootroot00000000000000 0. Introduction BART has a build system based on GNU Make. The build system offers many features for users and developers: BART can be built on different architectures, with different compilers, and with various optional features. This makes it easy to use BART in different environments, on a laptop, a multi-GPU system, a HPC cluster, or in the cloud. The build system also supports running system and unit tests. To make developing more fun, the makefile is optimized for extremely fast builds. Using parallel builds, BART can be built from scratch in about five seconds. After changing a single source code file it is usually possible to rebuild the binary in less than a second. This is accomplished by automatically maintaining dependencies between object files and incrementally updating the binaries from object stored in libraries. 1. Building BART 1.2. Main Build Targets 1.2.1. Default By default, the main 'bart' binary will be built with: make or make bart 1.2.1. Building Individual Commands Individual BART commands can be built as standalone binaries: make All BART commands can be built with: make all Attention: If the TOOLBOX_PATH is set, the 'bart' tool will call the standalone tool and not the built-in tool. This can be used to selectively update individual tools, but can also cause confusion. 1.2.2. Testing System and unit tests can be build and run with: make test make utest 1.2.3. Cleaning Up To clean up working directory, run: make clean To also remove all built commands, run: make allclean 1.3. Libraries As a side effect of build the main 'bart' tool, static libraries are generated in 'lib/'. 2. Local Configuration The build can be configured by setting or adding variables. 2.1. Makefile.local It is recommended to put this variables into a file called 'Makefile.local' in the main BART directory. This file is then automatically included. By having local configuration is a seperate file, local changes are not overwritten when BART is updated and do not cause conflicts when using a version control system. 2.2. Makefile. It is also possible to put machine-specific configurations variables in a Makefile. where is the name of the machine as returned by 'uname -n'. 2.3 Custom Makefiles directory Additional Makefiles can be included by placing them in the Makefiles directory. All files matching the expansion Makefiles/Makefile.* are automatically included in the build. See Makefiles/README.md for example files. 3. Build Options 3.1. Adding New BART Commands # add new tool (src/foo.c) to list of targets XTARGETS += foo # dependencies for foo MODULES_foo += -llowrank 3.2. Build Flags 3.2.1. Silent Builds Silent builds can be activated with the following option: MAKEFLAGS += --silent 3.3.2. Parallel Build Parallel builds can be activated with the following option: PARALLEL=1 3.3. Optional Features Some BART features are optional, because they depend on the other libraries or features which are not available everywhere. 3.3.1. CUDA Support for CUDA can be turned on. It may be necessary to also provide the base path for CUDA installation. CUDA=1 CUDA_BASE=/usr/ 3.3.2. OpenMP OpenMP can be turned off for compilers which do not support it properly (.e.g. clang): OMP=0 3.3.3. FFTW Threads It is possible to turn off FFTW threads if the library is not available: FFTWTHREADS=0 3.3.4. ISMRM Raw Data Format If the ISMRMRD library is installed, preliminary support for the ISMRM raw data format can be activated: ISMRMRD=1 3.4. Compiler 3.4.1. Different Compiler If different compilers or compiler versions are installed, it is possible to override the default compiler: CC = gcc-4.8 #CC = gcc-5 #CC = clang-3.5 3.4.2. Different CFLAGS Different CFLAGS can be set like this: CFLAGS= -g -O2 -ffast-math 3.4.3. Static Linking Static linking can be used to build binaries which do not depend on external shared libraries. This might be useful if BART is to be deployed on a different machine where it is difficult to install required dependencies. SLINK=1 bart-0.5.00/doc/cmake_building.txt000066400000000000000000000351671353046746100170140ustar00rootroot00000000000000 ___________________________ BART CMAKE BUILDING GUIDE ___________________________ Table of Contents _________________ 1 Overview 2 Building BART .. 2.1 Quick building guide ..... 2.1.1 Download and install LAPACKE locally ..... 2.1.2 Building of BART .. 2.2 Main Build Targets ..... 2.2.1 Default ..... 2.2.2 Testing ..... 2.2.3 Install ..... 2.2.4 Packaging ..... 2.2.5 Cleaning up .. 2.3 Non-standard locations (libraries, Python, etc.) 3 Build options .. 3.1 Adding new BART commands .. 3.2 Compiler ..... 3.2.1 Different compiler ..... 3.2.2 Different compiler flags .. 3.3 Optional Features 1 Overview ========== In addition to the GNU Make build system, BART can also be built using CMake which can offer more flexibility and portability when compiling on different architectures or platforms. Additionally, if you plan on integrating BART into other projects, the CMake build provide you with portable ways of installing and exporting BART which then allow you to easily add it as a dependency of your own project. If your other project is also based on CMake, adding BART as a dependency is as simple as writing `find_package(BART)' since all the dependencies are automatically taken care of. One key difference between the GNU Make and the CMake builds of BART is that the latter does not allow you to compile BART commands as separate executables. The BART executable is otherwise identical to the one generated by GNU Makefiles. 2 Building BART =============== At the very minimum, BART depends on a LAPACK/BLAS installation with C-bindings (CBLAS). Additionally, BART may profit from an optimized installation of LAPACKE (C interface to LAPACK), although you can specify an option to use an internal implementation of the necessary routines. Upon running for the first time, CMake will attempt to automatically find a compatible LAPACK/BLAS installation on your system. It will specifically look for: BLAS Only valid if the option `BART_NO_LAPACKE' is set. Will attempt to find valid `lapack', `cblas', and `blas' libraries. AMD_FLAME AMD's libFlame library OpenBLAS An optimized BLAS library ATLAS Automatically Tuned Linear Algebra Software LAPACKE C Interface to LAPACK (with cblas) If you have a particular vendor that you would like BART to link against, simply define the `LINALG_VENDOR' CMake variable with one of the above mentioned names (e.g. `cmake -DLINALG_VENDOR="ATLAS" ..'). 2.1 Quick building guide ~~~~~~~~~~~~~~~~~~~~~~~~ BART depends upon the new lapacke.h and cblas.h interfaces for blas and lapack. These new 'C' interfaces are often not packaged robustly on many different platforms. Important fixes to lapack distribution occured at lapack-3.6.0 and for finding lapack libs robustly with the github patch version 7fb63b1cd386b099d7da6eeaafc3e7dce055a7d0. List of issues when using default lapack from distributions: 1) Homebrew provides `lapacke.h', but not `cblas.h' 2) SUSE provides cblas.h from ATLAS, but `lapacke.h' from lapack distro 3) RHEL6 does not provide `lapacke.h' or `cblas.h' 4) RHEL7 does not provide `lapacke.h' or `cblas.h' Additionally, several 'Vendor' optimized versions provide enhanced lapack and blas intefaces with various levels of support for `lapacke.h' and `cblas.h'. Therefore for this short building guide, we suggest you download and compile the latest LAPACKE library and link BART against it. From inside the BART root directory issue the following command: ,---- | export ROOT_DIR=$PWD `---- 2.1.1 Download and install LAPACKE locally ------------------------------------------ Clone the LAPACK Git repository within the src/ folder of the BART root directory: ,---- | git clone https://github.com/Reference-LAPACK/lapack.git ${ROOT_DIR}/src/lapack | cd ${ROOT_DIR}/src/lapack | mkdir -p build | cd build | CC=gcc CXX=g++ FC=gfortran cmake -DCBLAS=ON -DLAPACKE=ON -DCMAKE_INSTALL_PREFIX=${ROOT_DIR}/lapack-install .. | make -j4 | make install `---- 2.1.2 Building of BART ---------------------- Now simply run CMake with the following variables: - `LINALG_VENDOR=LAPACKE' - `LAPACKE_ROOT=${ROOT_DIR}/lapack-install' For example, on UNIX from within the BART root directory: ,---- | mkdir -p ${ROOT_DIR}/bart-LAPACKE-bld | cd ${ROOT_DIR}/bart-LAPACKE-bld | rm -rf *; | CC=gcc CXX=g++ cmake -DCMAKE_Fortran_COMPILER=${FC} -DLINALG_VENDOR=LAPACKE -DLAPACKE_DIR=${ROOT_DIR}/lapack-install .. | make -j8 `---- 2.2 Main Build Targets ~~~~~~~~~~~~~~~~~~~~~~ 2.2.1 Default ------------- By default, the main BART executable, as well as the BARTmain library are built when no specific target are required (e.g. when issuing `make' on UNIX systems). Individual components may be built by choosing on of the following targets: bart Main BART executable bartmain BARTmain library with identical functionality as the main executable, but intended for embedding bartsupport BART library of support functions pyBART If enabled, will build the pyBART Python module 2.2.2 Testing ------------- The CMake build provides multiple targets for testing purposes: test Run all unit tests (NB: the `BUILD_TESTING' option must be turned `ON' and all targets must be built) integration Run all integration tests integration_XXX Run only the `XXX' tests (where `XXX' is for e.g. `cc', `fft', `pics', etc.) 2.2.3 Install ------------- The CMake build provides two installation targets: install Install everything that was built install_for_embedding Only install the BARTmain library and its related targets uninstall Remove all files installed during the last installation run 2.2.4 Packaging --------------- CPack is configured to produce self-installing archives on most platforms. These can be created by building the following target: package Create packaged archives of BART (platform dependent) 2.2.5 Cleaning up ----------------- To clean up the building directory, simply build the `clean' target (e.g. issuing `make clean' on UNIX) 2.3 Non-standard locations (libraries, Python, etc.) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you have some of your libraries installed in some non-standard locations (e.g. on UNIX outside of `/usr' or `/usr/local'), you can ask CMake to look for the requested libraries in other locations by defining either some environment variables or some CMake variables. Here is an exhaustive list of variables that may influence the building of BART: Variable name Type Description -------------------------------------------------------------------- CMAKE_PREFIX_PATH env./CMake Define good defaults for searching for packages ATLAS_ROOT env./CMake Preferred installation prefix ATLAS_DIR for the ATLAS libraries CUDA_ROOT env./CMake Preferred installation prefix CUDA_TOOLKIT_ROOT_DIR for the CUDA toolkit and libraries FFTW_ROOT env./CMake Preferred installation prefix FFTW_DIR for the FFTW libraries LAPACKE_ROOT env./CMake Preferred installation prefix LAPACKE_DIR for the LAPACKE libraries libFlame_ROOT env./CMake Preferred installation prefix libFlame_DIR for the AMD libFlame libraries OpenBLAS_ROOT env./CMake Preferred installation prefix OpenBLAS_DIR for the OpenBLAS libraries Python_ROOT_DIR env./CMake Define the root directory of a Python installation. Python_USE_STATIC_LIBS CMake only If not defined, search for shared libraries and static libraries in that order. If set to TRUE, search *only* for static libraries. If set to FALSE, search *only* for shared libraries. PYBART_NUMPY_ROOT env./CMake Define directory containing PYBART_NUMPY_DIR NumPy's arrayobject.h These variables would typicaly be used either as environment variables: ,---- | OpenBLAS_ROOT=/home/user/my_openblas Python_ROOT_DIR=/opt/anaconda/ cmake .. `---- or directly as CMake variables: ,---- | cmake .. -DOpenBLAS_ROOT=/home/user/my_openblas -DPython_ROOT_DIR=/opt/anaconda/ `---- 3 Build options =============== The CMake build can be configured by using a number of options provided in the main CMakeLists.txt file or by specifying them directly on the command line. 3.1 Adding new BART commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In order to register a new BART command, you need to copy the file containing its main function to `src' folder. Then either add its name somewhere inside the `build_targets.mk' file or define the `BART_EXTRA_PROGS' CMake variable with the name of your command. You then need to re-run the CMake configure step in order for the build system to properly register the new source file. 3.2 Compiler ~~~~~~~~~~~~ 3.2.1 Different compiler ------------------------ In order to specify a different compiler, either specify the controller you want on the command line when executing CMake: ,---- | CC=clang CXX=clang++ cmake [...] `---- or change the `CMAKE_C_COMPILER' and `CMAKE_CXX_COMPILER' variables in the CMake cache. 3.2.2 Different compiler flags ------------------------------ Compiler flags can be modified by modifying the `CMAKE_C_FLAGS' and `CMAKE_CXX_FLAGS' CMake variables, either from the command line when running CMake ,---- | cmake -DCMAKE_C_FLAGS=-Wall -DCMAKE_CXX_FLAGS=-Wall [...] `---- or by modifying their values in the CMake cache. 3.3 Optional Features ~~~~~~~~~~~~~~~~~~~~~ Some BART features are optional, either because they depend on libraries or features not available everywhere. All of them are controlled by CMake options that can be turned on or off: BART_CREATE_PYTHON_MODULE Turn on/off building of the `pyBART' Python module BART_DISABLE_PNG If `ON', disables building of the `toimg' BART command BART_ENABLE_MEM_CFL Turn on/off supports for in-memory CFL files BART_FFTWTHREADS Turn on/off support for threaded FFTW libraries BART_FPIC Turn on/off compilation using position independent code for all targets BART_GENERATE_DOC Turn on/off automatic generation of the documentation after building succeeds BART_ISMRMRD Turn on/off support for the ISMRM raw data format and its related command (`ismrmrd') BART_LOG_BACKEND Turn on/off support for external backends in the BARTmain library. Mainly intended for embedding purposes (e.g. with Gadgetron) BART_LOG_GADGETRON_BACKEND Turn on/off the Gadgetron logging backend (only displayed if BART_LOG_BACKEND is `ON') BART_LOG_ORCHESTRA_BACKEND Turn on/off the GE Orchestra logging backend (only displayed if BART_LOG_BACKEND is `ON') BART_LOG_SIEMENS_BACKEND Turn on/off the Siemens UTrace logging backend (only displayed if BART_LOG_BACKEND is `ON') BART_MATLAB Turn on/off building MATLAB-related tools (`mat2cfl') BART_MEMONLY_CFL Turn on/off enabling only in-memory CFL files. Note if `ON', BART will not be able to write files to the disk. BART_NO_LAPACKE If `ON', BART will use its internal implementation of the LAPACKE functions instead of relying on the ones installed on your system BART_REDEFINE_PRINTF_FOR_TRACE If `ON', `debug_print*' functions are re-defined as macros and that will forward their calls to their `debug_print*_trace' counterparts, thus providing more context information for error messages. Particularly useful in combination with external logging backends. BART_STATIC_ANALYSIS Turn on/off static analysis while building BART BART_SA_CLANG_TIDY Turn on/off running `clang-tidy' when compiling each file BART_SA_CPPCHECK Turn on/off running `cppcheck' during each compilation step BART_SA_IWYU Turn on/off running `include-what-you-use' for each file being compiled BUILD_TESTING Turn on/off building of unit test programs USE_CUDA Turn on/off support for CUDA (`OFF' by default). Detection of the location of the CUDA installation should work without modifications for standard installation prefixes. In the case where this automatic fails, you can set the `CUDA_TOOLKIT_ROOT_DIR' variable to the root directory of your CUDA installation (e.g. `/usr/local/cuda-9.2'). USE_CUDA_NATIVE This option is only shown if the `USE_CUDA' option is set. Turn on/off native CUDA support from CMake. Starting from CMake 3.8, support for CUDA as a separate language similar to C or C++ is possible. However, when integrating BART as a library in other projects it might be necessary to revert to the old behaviour of using the `FindCUDA' module. USE_OPENMP Support for OpenMP (`ON' by default), can be disabled by simply turning off this option. bart-0.5.00/doc/debugging.txt000066400000000000000000000015201353046746100157740ustar00rootroot00000000000000 Running a command in a debugger ------------------------------- This involves several (easy) steps: 1. Recompile BART with debugging information. Create a Makefile.local in the BART directory with the following line added: DEBUG=1 Then recompile with: make allclean make bart 2. Install the GNU debugger (gdb) 3. Run the failing BART command: gdb --args bart [ ...] ... 4. Then type 'run' to start the process. If it crashes, you are back in the debugger. You can also type CTRL-C to interrupt it at any time. In the debugger: You can type 'bt' to get a backtrace which is helpful to investigate a segmentation fault or similar. You can also call functions. For example, this can be used to save a multi-dimensional array from the debugger like this: (gdb) call dump_cfl("dbg_img", 16, dims, image) bart-0.5.00/doc/dimensions-and-strides.txt000066400000000000000000000037031353046746100204310ustar00rootroot00000000000000 BART is built around a library which defines many generic functions on multi-dimensional arrays. Most functions come in two flavours: A basic version (e.g. 'md_copy') which takes as input the dimensions for its arguments and an extended version (e.g. 'md_copy2') which also takes the strides for each argument. The basic versions assume strides for a column-major array which is contiguous in memory. A stride refers to the distance in memory between successive elements in an array. They are used to compute the position of an element in memory for a given multi-index by multiplying the index of each dimension with the corresponding stride and summing the results. For a regular array of complex floats continuously laid out in memory with dimensions 'dim[N]' the default strides are: str[0] = sizeof(complex float) str[1] = dim[0] * sizeof(complex float) str[2] = dim[0] * dim[1] * sizeof(complex float) ... There is one exception: For a dimension with length one, the corresponding stride is set to zero. These default strides are what the function 'md_calc_strides' computes and which are also used automatically whenever strides are not explicitly specified. Dimensions and strides can be manipulated to obtain different views of the same array without having to make a copy. For example, swapping dimensions and strides for two indices yields a transposed view of the array, an increased stride yields a view of a sub-array, a negative stride a view where the corresponding dimension is reversed (flipped), and a zero stride yields a view in which one dimension is replicated. Many basic functions such as 'md_transpose', 'md_flip', 'md_slice', 'md_copy_block' etc. are implemented in this way by setting up dimensions and strides and calling into the generic copy function 'md_copy2'. Even much more complicated operations can often be implemented in just a few lines of code. One example is building a Casorati matrix of overlapping blocks (see 'num/casorati.c'). bart-0.5.00/doc/fft.txt000066400000000000000000000042311353046746100146220ustar00rootroot00000000000000 Centered FFT ------------ The center is N / 2 for even N and (N - 1) / 2 for odd N when counting from zero. Instead of using fftshift/ifftshift we usually use fftmod/ifftmod. While fftshift/ifftshift involves a cyclic copy of memory, fftmod applies a linear phase which has a similar effect. We prefer fftmod because we can usually merge this phase with other operations to reduce computation time. Though similar, there are some subtle differences which one has to keep in mind. The correct use of fftshift/ifftshift for a centered forward/inverse FFT is the following: forward: 1. ifftshift 2. fft 3. fftshift inverse: 1. ifftshift 2. ifft 3. fftshift In contrast, the correct use of fftmod/ifftmod for a centered forward/inverse FFT is this: forward: 1. fftmod 2. fft 3. fftmod inverse: 1. ifftmod 2. ifft 3. ifftmod If \xi_N is the N-th root of unity with smallest positive complex argument, the uncentered forward DFT of length N is: \hat f(k) = \sum_{x=0}^{N-1} \xi_N^{-xk} f(x) Shifting the center from index 0 to new index c yields the formula for the centered forward DFT of length N: \hat f_c(k) = \sum_{x=0}^{N-1} \xi_N^{-(x-c)(k-c)} f_c(x) Note that this corresponds to shifts in different directions for input and output. Expanding the exponent yields: (x-c)(k-c) = xk - xc - ck + c^2 Thus, the centered FFT can be implemented by multiplication with a linear phase before and after calling the uncentered FFT: \hat f(k) = \xi_N^{(k-c/2)c} \sum_{x=0}^{N-1} \xi_N^{-xk} \x_N^{(x-c/2)c} f(x) Observe that this is the same linear phase applied to the input and output. Note that we distributed the additional phase \xi^{-c^2} evenly to both terms. If N is a multiple of four, then c^2 = N (N/4) and the additional phase term vanishes. Then \xi_N^{kc} and \xi_N^{xc} are simply the alternating sequence of 1, -1, 1, -1, ... Because ifftmod applies the conjugate phase this implies that it is the same as fftmod in this special case. If N is a multiple of two, the additional phase is -pi/2. Evenly distributed this yields a factor of '-i' (i the imaginary number), i.e. fftmod applies -i, +i, -i, +i, ... For N odd the phase is more complicated. bart-0.5.00/doc/references.txt000066400000000000000000000234321353046746100161700ustar00rootroot00000000000000 - BART - Uecker M, Ong F, Tamir JI, Bahri D, Virtue P, Cheng JY, Zhang T, Lustig M. Berkeley Advanced Reconstruction Toolbox. Annual Meeting ISMRM, Toronto 2015, In: Proc Intl Soc Mag Reson Med 2015; 23:2486. Uecker M, Virtue P, Ong F, Murphy MJ, Alley MT, Vasanawala SS, Lustig M. Software Toolbox and Programming Library for Compressed Sensing and Parallel Imaging, ISMRM Workshop on Data Sampling and Image Reconstruction, Sedona 2013. Tamir JI, Ong F, Cheng JY, Uecker M, Lustig M. Generalized Magnetic Resonance Image Reconstruction using The Berkeley Advanced Reconstruction Toolbox, ISMRM Workshop on Data Sampling and Image Reconstruction, Sedona 2016. - reproducible publications using BART - Uecker M, Lustig M. Estimating Absolute-Phase Maps Using ESPIRiT and Virtual Conjugate Coils. Magn Reson Med 2017; 77:1201-1207. https://github.com/mrirecon/vcc-espirit Rosenzweig S, Holme HCM, Wilke RN, Voit D, Frahm J, Uecker M. Simultaneous Multi-Slice Reconstruction Using Regularized Nonlinear Inversion: SMS-NLINV. Magn Reson Med 2018; 79:2057-2066. https://github.com/mrirecon/sms-nlinv Rosenzweig S, Holme HCM, Uecker M. Simple Auto-Calibrated Gradient Delay Estimation From Few Spokes Using Radial Intersections (RING). Magn Reson Med 2019; 81:1898-1906. https://github.com/mrirecon/ring Holme HCM, Rosenzweig S, Ong F, Wilke RN, Lustig M, Uecker M. ENLIVE: An Efficient Nonlinear Method for Calibrationless and Robust Parallel Imaging. Scientific Reports 2019; 9:3034. https://github.com/mrirecon/enlive - sensitivity-encoded parallel imaging - (commands: itsense, pocsense, bpsense, pics) Ra JB and Rim CY. Fast imaging using subencoding data sets from multiple detectors. Magn Reson Med 1993; 30:142-145. Pruessmann KP, Weiger M, Scheidegger MB, Boesiger P. SENSE: Sensitivity encoding for fast MRI. Magn Reson Med 1999; 42:952-962. Pruessmann KP, Weiger M, Boernert P, Boesiger P. Advances in sensitivity encoding with arbitrary k-space trajectories. Magn Reson Med 2001; 46:638-651. Samsonov AA, Kholmovski EG, Parker DL, Johnson CR. POCSENSE: POCS-based reconstruction for sensitivity encoded magnetic resonance imaging. Magn Reson Med 2004; 52:1397-1406. - implementation of the (non-uniform) FFT - (commands: fft, nufft, pics) O’Sullivan JD. A fast sinc function gridding algorithm for Fourier inversion in computer tomography. IEEE Trans Med Imaging 1985; 4:200-207. Jackson JI, Meyer CH, Nishimura DG, Macovski A. Selection of a convolution function for Fourier inversion using gridding. IEEE Trans Med Imaging 1991; 3:473-478. Wajer F and Pruessmann KP. Major speedup of reconstruction for sensitivity­encoding with arbitrary trajectories. Annual Meeting of the ISMRM, Glasgow 2001, In: Proc Intl Soc Mag Reson Med 2001; 9:767. Frigo M, Johnson SG. The Design and Implementation of FFTW3. Proc IEEE 2005; 93:216-231. Uecker M, Zhang S, Frahm J. Nonlinear Inverse Reconstruction for Real-time MRI of the Human Heart Using Undersampled Radial FLASH. Magn Reson Med 2010; 63:1456-1462. Ong F, Uecker M, Jiang W, Lustig M. Fast Non-Cartesian Reconstruction with Pruned Fast Fourier Transform. Annual Meeting ISMRM, Toronto 2015, In: Proc Intl Soc Mag Reson Med 2015; 23:3639. - methods for sensitivity calibration - (commands: walsh, caldir, ecalib, ecaltwo) Walsh DO, Gmitro AF, Marcellin MW. Adaptive reconstruction of phased array MR imagery. Magn Reson Med 2000; 43:682-690. Griswold M, Walsh D, Heidemann R, Haase A, Jakob A. The Use of an Adaptive Reconstruction for Array Coil Sensitivity Mapping and Intensity Normalization Annual Meetig ISMRM, Honolulu 2002, In: Proc Intl Soc Mag Reson Med 2002; 10:2410. McKenzie CA, Yeh EN, Ohliger MA, Price MD, Sodickson DK. Self-calibrating parallel imaging with automatic coil sensitivity extraction. Magn Reson Med 2002; 47:529-538. Uecker M, Virtue P, Vasanawala SS, Lustig M. ESPIRiT Reconstruction Using Soft SENSE. Annual Meeting ISMRM, Salt Lake City 2013, In: Proc Intl Soc Mag Reson Med 2013; 21:127. Uecker M, Lai P, Murphy MJ, Virtue P, Elad M, Pauly JM, Vasanawala SS, Lustig M. ESPIRiT - An Eigenvalue Approach to Autocalibrating Parallel MRI: Where SENSE meets GRAPPA. Magn Reson Med 2014; 71:990-1001. - joint estimation: nonlinear inversion, calibrationless - (commands: nlinv, sake) Uecker M, Hohage T, Block KT, Frahm J. Image reconstruction by regularized nonlinear inversion-joint estimation of coil sensitivities and image content. Magn Reson Med 2008; 60:674-682. Bi Z, Uecker M, Jiang D, Lustig M, Ying K. Robust Low-rank Matrix Completion for sparse motion correction in auto calibration PI. Annual Meeting ISMRM, Salt Lake City 2013, In: Proc Intl Soc Mag Reson Med 2013; 21:2584. Shin PJ, Larson PEZ, Ohliger MA, Elad M, Pauly JM, Vigneron DB, Lustig M. Calibrationless Parallel Imaging Reconstruction Based on Structured Low-Rank Matrix Completion. Magn Reson Med 2014; 72:959-970. Holme HCM, Rosenzweig S, Ong F, Wilke RN, Lustig M, Uecker M. ENLIVE: An Efficient Nonlinear Method for Calibrationless and Robust Parallel Imaging. Scientific Reports 2019; 9:3034. - coil compression - (command: cc) Buehrer M, Pruessmann KP, Boesiger P, Kozerke S. Array compression for MRI with large coil arrays. Magn Reson Med 2007, 57:1131-1139. Huang F, Vijayakumar S, Li Y, Hertel S, Duensing GR. A software channel compression technique for faster reconstruction with many channels. Magn Reson Imaging 2008; 26:133-141. Zhang T, Pauly JM, Vasanawala SS, Lustig M. Coil compression for accelerated imaging with cartesian sampling. Magn Reson Med 2013; 69:571-582. Bahri D, Uecker M, Lustig M. ESPIRiT-Based Coil Compression for Cartesian Sampling. Annual Meeting ISMRM, Salt Lake City 2013, In: Proc Intl Soc Mag Reson Med 2013; 21:2657. - compressed sensing MRI - (commands: pocsense, pics) Block KT, Uecker M, Frahm J. Undersampled radial MRI with multiple coils. Iterative image reconstruction using a total variation constraint. Magn Reson Med 2007; 57:1086-1098. Lustig M, Donoho D, Pauly JM. Sparse MRI: The application of compressed sensing for rapid MR imaging. Magn Reson Med 2007; 58:1182-1195. Liu B, King K, Steckner M, Xie J, Sheng J, Ying L. Regularized sensitivity encoding (SENSE) reconstruction using Bregman iterations. Magn Reson Med 2009; 61:145-152. - model-based reconstruction - (commands: moba, pics) Block KT, Uecker M, Frahm J. Model-Based Iterative Reconstruction for Radial Fast Spin-Echo MRI. IEEE Trans Med Imag 2019; 28:1759-1769. Petzschner FH, Ponce IP, Blaimer M, Jakob PM, Breuer FA. Fast MR parameter mapping using kâ€t principal component analysis. Magn Reson Med 2011; 66;706-716. Mani M, Jacob M, Magnotta V, Zhong J. Fast iterative algorithm for the reconstruction of multishot non-cartesian diffusion data. Magn Reson Med 2015; 74:1086–1094. Wang X, Roeloffs V, Klosowski J, Tan Z, Voit D, Uecker M, Frahm J. Model-based T1 Mapping with Sparsity Constraints Using Single-Shot Inversion-Recovery Radial FLASH. Magn Reson Med 2018; 79:730-740. - sparsity transforms, variational penalties, regularization - (commands: cdf97, rof, tgv, lrmatrix, pocsense, pics) Rudin LI, Osher S, Fatemi E. Nonlinear total variation based noise removal algorithms, Physica D: Nonlinear Phenomena 1992; 60:259-268. Figueiredo MAT and Nowak RD. An EM algorithm for wavelet-based image restoration. IEEE Trans Image Process 2003; 12:906-916. Ong F, Uecker M, Tariq U, Hsiao A, Alley MT, Vasanawala SS, Lustig M. Robust 4D Flow Denoising using Divergence-free Wavelet Transform, Magn Reson Med 2015; 73:828-842. Ong F, Lustig M. Beyond low rank + sparse: Multi-scale low rank matrix decomposition, IEEE J Sel Topics Signal Process 2016; 10:672-687. Bredies K, Kunisch K, Pock T. Total generalized variation. SIAM Journal on Imaging Sciences 2010; 3:492-526. - sampling schemes - (commands: traj, poisson, wave, wavepsf) Winkelmann S, Schaeffter T, Koehler T, Eggers H, Doessel O. An optimal radial profile order based on the Golden Ratio for time-resolved MRI. IEEE Trans Med Imaging 2007; 26:68-76. Lustig M, Alley M, Vasanawala S, Donoho DL, Pauly JM. L1 SPIR-iT: Autocalibrating Parallel Imaging Compressed Sensing Annual Meeting ISMRM, Honolulu 2009, In: Proc Intl Soc Mag Reson Med 2009; 17:379. Bilgic B, Gagoski BA, Cauley SF, Fan AP, Polimeni JR, Grant PE, Wald LL, Setsompop K. Wave-CAIPI for highly accelerated 3D imaging. Magn Reson Med 2014; 73:2152-2162. Wundrak S, Paul J, Ulrici J, Hell E, Geibel M-A, Bernhardt P, Rottbauer W, Rasche V. Golden ratio sparse MRI using tiny golden angles. Magn Reson Med 2016; 75:2372-2378. - trajectory correction - (commands: estdelay) Block KT, Uecker M. Simple Method for Adaptive Gradient-Delay Compensation in Radial MRI. Annual Meeting ISMRM, Montreal 2011, In: Proc. Intl. Soc. Mag. Reson. Med 2011; 19:2816. Rosenzweig S, Holme HCM, Uecker M. Simple Auto-Calibrated Gradient Delay Estimation From Few Spokes Using Radial Intersections (RING). Magn Reson Med 2019; 81:1898-1906. - acceleration with graphical processing units - (commands: pocsense, nufft, pics, nlinv) Uecker M, Zhang S, Frahm J. Nonlinear Inverse Reconstruction for Real-time MRI of the Human Heart Using Undersampled Radial FLASH. Magn Reson Med 2010; 63:1456-1462. Murphy M, Alley M, Demmel J, Keutzer K, Vasanawala S, Lustig M. Fast â„“1-SPIRiT Compressed Sensing Parallel Imaging MRI: Scalable Parallel Implementation and Clinically Feasible Runtime. IEEE Trans Med Imaging 2012; 31:1250-1262. - numerical phantoms - (command: phantom) Shepp LA, Logan BF. The Fourier reconstruction of a head section. IEEE T Nucl Sci 1974; 21:21-43. Koay CG, Sarlls JE, Özarslan E. Three-Dimensional Analytical Magnetic Resonance Imaging Phantom in the Fourier Domain. Magn Reson Med 2007; 58:430-436. Guerquin-Kern M, Lejeune L, Pruessmann KP, M Unser M, Realistic Analytical Phantoms for Parallel Magnetic Resonance Imaging. IEEE Trans Med Imaging 2012; 31:626-636. bart-0.5.00/doc/style.txt000066400000000000000000000103631353046746100152060ustar00rootroot00000000000000 1. Language The main language is C11 with commonly used GNU extensions (gnu11) as supported by the GCC and clang compilers. 1.1. Standard types: The complex types are the standard types introduced with ISO C99. #include complex float complex double In headers we use _Complex without including the standard header for complex types for compatibility with C++. Similarly, we use the standard boolean type. #include bool x = true; 1.2. Arrays Large multi-dimensional arrays should use our md_* functions. Small arrays should use (variable-length) arrays to increase type-safety. Pointer arithmetic should be avoided. float kernel[N][3]; complex float* image = md_alloc(N, dims, CFL_SIZE); In headers, we use the __VLA(x) macro for compatibility with C++ when this is possible. 1.2. GNU Extensions: Some extensions a commonly supported by compilers and useful. statement expressions ({ }) __typeof__ const array parameters 1.3. Type safety void* and casts should be used only when necessary. Functions must have a prototype. Variable-length arrays are preferred over basic pointers. Macros can often be made type-safe, e.g. using the TYPE_CHECK macro. 2. Coding Style Coding style are meant as guidelines. It is OK to deviate from the guidelines in situations, if it helps to make the code easier to understand. 2.1. Indentation Indentation using a single tab. A tab is considered 8 characters. White space errors (white space after the last visible character of a line) should be avoided. 2.2. Expressions There should be no space after the opening or before the closing bracket. There should be a single space before and after any operator except for prefix and postfix operators. Subexpressions should be enclosed in brackets and not rely on operator precedence for correct evaluation order. int i = (3 + x++) * 2; If there is a constant involved in a comparison the constant should be on the left side. if (0. == x) return false; The type of the controlling expression used in if statements or loops should be boolean. Pointers and integers should not implicitly compared to NULL or zero. if (NULL == foo_ptr) foo_ptr = init_foo_ptr(); 2.3. Statement groups. Opening curly brace is on the next line for functions and on the same line for if, for, while, and switch statements. In the later case there should be an empty line afterwards. In case only a single statement follows an if, for, or while statement, the statement block can be omitted - but for if-else pairs only it can be omitted on both sides. There should be no empty line before the closing bracket. if (0. == x) { ... } if (0. == x) y = 3; Statements should be grouped in logical blocks by a single empty line. In particular, declarations, definitions (with initialization) should be separated from other statements. Memory allocation and deallocation should usually be separated. void compute_bar(complex float* bar) { complex float* foo = md_alloc(); compute_foo(foo); compute_bar_from_foo(bar, foo); md_free(foo); } 2.4. Comments: Comments should be used to document the API, explain complicated code and algorithms, and give required background information. Comments are not meant to explain things a competent programmer should know by reading the code. Good: // gram-schmidt algorithm for (...) { for (..) { ... } } Bad: // initialize foo int foo = 3; // config struct struct foo_conf_s conf = ... // allocate memory complex float* x = md_alloc(...); 2.5. Variable and Function Names Functions and variables names should be lower case and use '_' has separator of components. Names should be meaningful but not unnecessary long. If possible, use self-explanatory variable names. Except for loop indices, where one-letter variables names can be used. float norm = calc_frobenius_norm(image) This is preferable to adding comments: // calculate frobenous norm float n = clc_frbn(i); On the other hand, for often used functions a short name is appropriate. For example, we use md_fmac() instead of multidim_fused_multiply_accumulate() Locally used loop indices can be single character letters: i, j, k bart-0.5.00/doxyconfig000066400000000000000000002342221353046746100146360ustar00rootroot00000000000000# Doxyfile 1.8.3.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = "Berkeley Advanced Reconstruction Toolbox (BART)" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. #PROJECT_NUMBER = 0.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "" # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc/dx/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.cu *.h *.py *.m # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = src/spirit-1.0 src/spirit-2.0 src/butterfly # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id # of to a relative location where the documentation can be found. # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES bart-0.5.00/genctags000077500000000000000000000001251353046746100142540ustar00rootroot00000000000000#!/bin/bash ctags --langmap=c++:+.cu --extra=+f `find . -regex '.*\.[ch]u*' -print` bart-0.5.00/git-version.sh000077500000000000000000000004131353046746100153400ustar00rootroot00000000000000#!/bin/bash if test -d ${GIT_DIR:-.git} -o -f .git then git describe --match "v*" --dirty if [[ $? -eq 0 ]]; then git describe --match "v*" | cut -f1 -d'-' > version.txt else var=`cat version.txt` echo ${var}-dirty fi else cat version.txt fi bart-0.5.00/lib/000077500000000000000000000000001353046746100133035ustar00rootroot00000000000000bart-0.5.00/lib/.gitignore000066400000000000000000000001071353046746100152710ustar00rootroot00000000000000# Ignore everything in this directory * # Except this file !.gitignore bart-0.5.00/makedoc.sh000077500000000000000000000001271353046746100144770ustar00rootroot00000000000000#!/bin/bash ( cat doxyconfig ; echo "PROJECT_NUMBER=$(cat version.txt)" ) | doxygen - bart-0.5.00/matlab/000077500000000000000000000000001353046746100137755ustar00rootroot00000000000000bart-0.5.00/matlab/WSLPathCorrection.m000066400000000000000000000007161353046746100174710ustar00rootroot00000000000000%Soumick Chatterjee function [outData] = WSLPathCorrection(inData) outData=inData; for i = 'a':'z' %Replace drive letters with /mnt/ outData=strrep(outData,[i,':'],['/mnt/',i]); %if drive letter is supplied in lowercase outData=strrep(outData,[upper(i),':'],['/mnt/',i]); %if drive letter is supplied as uppercase end outData = strrep(outData, '\', '/'); %Change windows filesep to linux filesep end bart-0.5.00/matlab/bart.m000066400000000000000000000047311353046746100151100ustar00rootroot00000000000000function [varargout] = bart(cmd, varargin) % BART Call BART command from Matlab. % [A, B] = bart('command', X, Y) call command with inputs X Y and outputs A B % % 2014-2016 Martin Uecker % Edited for WSL, by Soumick Chatterjee if nargin==0 || all(cmd==0) disp('Usage: bart '); return end bart_path = getenv('TOOLBOX_PATH'); isWSL = false; if isempty(bart_path) if exist('/usr/local/bin/bart', 'file') bart_path = '/usr/local/bin'; elseif exist('/usr/bin/bart', 'file') bart_path = '/usr/bin'; else % Try to execute bart inside wsl, if it works, then it returns % status 0 [bartstatus, ~] = system('wsl bart version -V'); if bartstatus==0 bart_path = '/usr/bin'; isWSL = true; else error('Environment variable TOOLBOX_PATH is not set.'); end end end % clear the LD_LIBRARY_PATH environment variable (to work around % a bug in Matlab). if ismac==1 setenv('DYLD_LIBRARY_PATH', ''); else setenv('LD_LIBRARY_PATH', ''); end name = tempname; in = cell(1, nargin - 1); for i=1:nargin - 1 in{i} = strcat(name, 'in', num2str(i)); writecfl(in{i}, varargin{i}); end in_str = sprintf(' %s', in{:}); out = cell(1, nargout); for i=1:nargout out{i} = strcat(name, 'out', num2str(i)); end out_str = sprintf(' %s', out{:}); if ispc if isWSL % For WSL and modify paths cmdWSL = WSLPathCorrection(cmd); in_strWSL = WSLPathCorrection(in_str); out_strWSL = WSLPathCorrection(out_str); ERR = system(['wsl bart ', cmdWSL, ' ', in_strWSL, ' ', out_strWSL]); else % For cygwin use bash and modify paths ERR = system(['bash.exe --login -c ', ... strrep(bart_path, filesep, '/'), ... '"', '/bart ', strrep(cmd, filesep, '/'), ' ', ... strrep(in_str, filesep, '/'), ... ' ', strrep(out_str, filesep, '/'), '"']); end else ERR = system([bart_path, '/bart ', cmd, ' ', in_str, ' ', out_str]); end for i=1:nargin - 1 if (exist(strcat(in{i}, '.cfl'),'file')) delete(strcat(in{i}, '.cfl')); end if (exist(strcat(in{i}, '.hdr'),'file')) delete(strcat(in{i}, '.hdr')); end end for i=1:nargout if ERR==0 varargout{i} = readcfl(out{i}); end if (exist(strcat(out{i}, '.cfl'),'file')) delete(strcat(out{i}, '.cfl')); end if (exist(strcat(out{i}, '.hdr'),'file')) delete(strcat(out{i}, '.hdr')); end end if ERR~=0 error('command exited with an error'); end end bart-0.5.00/matlab/readcfl.m000066400000000000000000000020511353046746100155510ustar00rootroot00000000000000function data = readcfl(filenameBase) %READCFL Read complex data from file. % Read in reconstruction data stored in filenameBase.cfl (complex float) % based on dimensions stored in filenameBase.hdr. % % Written to edit data with the Berkeley Advanced Reconstruction Toolbox (BART). % % Copyright 2016. CBClab, Maastricht University. % 2016 Tim Loderhose (t.loderhose@student.maastrichtuniversity.nl) dims = readReconHeader(filenameBase); filename = strcat(filenameBase,'.cfl'); fid = fopen(filename); data_r_i = fread(fid, prod([2 dims]), '*float32'); data_r_i = reshape(data_r_i, [2 dims]); data = complex(zeros(dims,'single'),0); data(:) = complex(data_r_i(1,:),data_r_i(2,:)); fclose(fid); end function dims = readReconHeader(filenameBase) filename = strcat(filenameBase,'.hdr'); fid = fopen(filename); line = getNextLine(fid); dims = str2num(line); fclose(fid); end function line = getNextLine(fid) line = fgetl(fid); while(line(1) == '#') line = fgetl(fid); end end bart-0.5.00/matlab/writecfl.m000066400000000000000000000021221353046746100157670ustar00rootroot00000000000000function writecfl(filenameBase,data) %WRITECFL Write complex data to file. % Writes reconstruction data to filenameBase.cfl (complex float) and its % dimensions to filenameBase.hdr. % % Written to edit data with the Berkeley Advanced Reconstruction Toolbox (BART). % % Copyright 2013. Joseph Y Cheng. % Copyright 2016. CBClab, Maastricht University. % 2012 Joseph Y Cheng (jycheng@mrsrl.stanford.edu). % 2016 Tim Loderhose (t.loderhose@student.maastrichtuniversity.nl). dims = size(data); writeReconHeader(filenameBase,dims); filename = strcat(filenameBase,'.cfl'); fid = fopen(filename,'w'); data = data(:); fwrite(fid,[real(data)'; imag(data)'],'float32'); fclose(fid); end function writeReconHeader(filenameBase,dims) filename = strcat(filenameBase,'.hdr'); fid = fopen(filename,'w'); fprintf(fid,'# Dimensions\n'); for N=1:length(dims) fprintf(fid,'%d ',dims(N)); end if length(dims) < 5 for N=1:(5-length(dims)) fprintf(fid,'1 '); end end fprintf(fid,'\n'); fclose(fid); end bart-0.5.00/packaging/000077500000000000000000000000001353046746100144615ustar00rootroot00000000000000bart-0.5.00/packaging/CPackConfig.cmake000066400000000000000000000200471353046746100175750ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen # ============================================================================== # # Inspired by https://github.com/kracejic/cleanCppProject # Copyright (c) 2018 Kracejic # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # ============================================================================== include(InstallRequiredSystemLibraries) set(CPACK_PACKAGE_VENDOR "UC Berkeley") set(CPACK_PACKAGE_CONTACT "Martin Uecker ") set(HOMEPAGE "https://github.com/mrirecon/bart") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The Berkeley Advanced Reconstruction Toolbox (BART) toolbox is a free and open-source image-reconstruction framework for Computational Magnetic Resonance Imaging.") set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt") set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/packaging) set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}") # Generate .txt license file for CPack (PackageMaker requires a file extension) configure_file(${PROJECT_SOURCE_DIR}/LICENSE ${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt @ONLY) # set human names to exetuables set(CPACK_PACKAGE_EXECUTABLES "bart;bart") set(CPACK_CREATE_DESKTOP_LINKS "bart") if(TARGET mat2cfl) list(APPEND CPACK_PACKAGE_EXECUTABLES mat2cfl mat2cfl) list(APPEND CPACK_CREATE_DESKTOP_LINKS mat2cfl) endif() set(CPACK_STRIP_FILES TRUE) # ============================================================================== if(WIN32 AND NOT UNIX) #--------------------------------------------------------------------------- # Windows specific set(CPACK_GENERATOR "STGZ;ZIP") message(STATUS "Package generation - Windows") message(STATUS " + STGZ YES ") message(STATUS " + ZIP YES ") # NSIS windows installer find_program(NSIS_PATH nsis PATH_SUFFIXES nsis) if(NSIS_PATH) set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") message(STATUS " + NSIS YES ") # Note: There is a bug in NSI that does not handle full unix paths # properly. # Make sure there is at least one set of four (4) backlasshes. set(CPACK_NSIS_DISPLAY_NAME ${CPACK_PACKAGE_NAME}) # Icon of the installer set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\packaging\\\\bart.ico") set(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.mrirecon.github.io\\\\bart") set(CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}") set(CPACK_NSIS_MODIFY_PATH ON) else() message(STATUS " + NSIS NO ") endif() set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\bart.png") # Configure file with right path, place the result to PROJECT_BINARY_DIR. # When ${PROJECT_BINARY_DIR}/bart.icon.rc is added to an executable # it will have icon specified in bart.icon.in.rc configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packaging/bart.icon.in.rc ${PROJECT_BINARY_DIR}/bart.icon.rc) elseif(APPLE) #--------------------------------------------------------------------------- # Apple specific set(CPACK_GENERATOR "ZIP;STGZ") message(STATUS "Package generation - MacOSX") message(STATUS " + Application Bundle NO ") message(STATUS " + ZIP YES ") else() #--------------------------------------------------------------------------- # Linux specific set(CPACK_GENERATOR "DEB;TBZ2;STGZ") message(STATUS "Package generation - UNIX") message(STATUS " + DEB YES ") message(STATUS " + TBZ2 YES ") message(STATUS " + STGZ YES ") find_program(RPMBUILD_PATH rpmbuild) if(RPMBUILD_PATH) message(STATUS " + RPM YES ") set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") set(CPACK_RPM_PACKAGE_LICENSE "3-Clause BSD License") set(CPACK_RPM_PACKAGE_REQUIRES "fftw3, blas") if(NOT BART_DISABLE_PNG) set(CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES}, libpng") endif() # if(NOT BART_NO_LAPACKE) # set(CPACK_RPM_PACKAGE_REQUIRES # "${CPACK_RPM_PACKAGE_REQUIRES}, liblapacke") # endif() # exclude folders which clash with default ones set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST} /usr /usr/bin /usr/share /usr/share/applications /usr/share/doc /usr/share/icons /usr/share/icons/hicolor /usr/share/icons/hicolor/256x256 /usr/share/icons/hicolor/256x256/apps /usr/share/icons/gnome /usr/share/icons/gnome/256x256 /usr/share/icons/gnome/256x256/apps) else() message(STATUS " + RPM NO ") endif() set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${HOMEPAGE}") # set(CPACK_DEBIAN_COMPRESSION_TYPE "xz") set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfftw3-dev, libblas3") # FIXME: should really be something like libfftw3-3 if(NOT BART_DISABLE_PNG) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}, libpng-dev") # FIXME: should really be something like libpng16 endif() # if(NOT BART_NO_LAPACKE) # set(CPACK_DEBIAN_PACKAGE_DEPENDS # "${CPACK_DEBIAN_PACKAGE_DEPENDS}, liblapacke") # endif() # Icon and app shortcut for Linux systems # Note: .desktop file must have same name as executable # install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/bart.desktop # DESTINATION share/applications/ # PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ # ) # install(FILES ${PROJECT_SOURCE_DIR}/packaging/bart.png # DESTINATION share/icons/hicolor/256x256/apps/ # PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ # ) # install(FILES ${PROJECT_SOURCE_DIR}/packaging/bart.png # DESTINATION share/icons/gnome/256x256/apps/ # PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ # ) # License file install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt DESTINATION ${CMAKE_INSTALL_DOCDIR} PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ RENAME copyright) # set package icon set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/bart.png") endif() # ============================================================================== include(CPack) bart-0.5.00/packaging/bart.ico000066400000000000000000002666761353046746100161340ustar00rootroot00000000000000  ¨F@@ (B (S €>[( @ #.#.CCCCC@tûøøøøí/fffgÉ÷    ¥ùSÅÄűFcÉaCÅ“¦¯ª·%rÆE¥ùmÿú÷ÿÙ}ý¤}ÿ‘ÒäHúÄ”ÿY¥ùmÿ‘9·ÿŠäÞ{uÊù]ÑäŽÿ}”ÿY¥ùmÿrvÿƒ¼ÿÿÿÿÞ4Óã4Íò9”ÿY“Þmÿx”ÿb‰ÿ° þ´Ôô¶ùÇ”ÿY mÿàÉóÎWÿwRÿÓÿÿÿå?”ÿYmÿìäÿª*짇üKÔðwÿ§”ÿYlÿ»õ= Ç×Åä!Õä!åÒ”ÿYÇ«lÿr•ÿZ”üú¹ÕäáØ”ÿYàÀlÿ—LÏûJ]ýÿƒÕìY}ûÃ?C±ÿ†B&àÀlÿýýÿÊ.ëûOÓÿüþú{ÁÿþÿýÿàÀN¹¸¸›4˜ª˜º¹³nŽ»¸¸¸»gàÀ ÞÚkefg5Õùøøøü‚9CCCCD#ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿ€ÿÿÿ€àŒˆà ˆàˆàˆâˆàŒàà  !!añ†ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(@€ @#.#. ^qpppppppppqfÖÿÿÿÿÿÿÿÿÿÿÿéÖÿÿÿÿÿÿÿÿÿÿÿ霻ºººººº¸Òÿÿé^þÿéYþÿéYþÿé|£¡¡¡¡¡˜_"˜¡£€ S£¡£]z£¢v£¡¡B&š¡£fYþÿé ÆÿÿÿÿÿÿÿüÀ*Úÿÿã#¦ÿÿýjÀÿÿã!#àÿÿð:<õÿÿ¢Yþÿé Æÿÿÿÿÿÿÿÿÿ¼¬ÿÿ÷EÌÿÿê9Áÿÿã!ZüÿÿÀ <õÿÿ¢Yþÿé ÆÿÿÿþýþÿÿÿüZuÿÿÿo+éÿÿÆÃÿÿã!¢ÿÿÿ{<õÿÿ¢Yþÿé ÆÿÿßbV`ÅÿÿÿJ÷ÿÿ Yúÿÿ˜ Äÿÿã! Ýÿÿï8<õÿÿ¢Yþÿé ÆÿÿÎ>ïÿÿÃ+ÝÿÿðÔÓÓÓãÿÿÿdÄÿÿã!XûÿÿÀ <õÿÿ¢Yþÿé ÆÿÿÎÔÿÿײÿÿÿÿÿÿÿÿÿÿî3Äÿÿã!™ÿÿÿ{<õÿÿ¢Yþÿé ÆÿÿÎÑÿÿØ|ÿÿÿÿÿÿÿÿÿÿÌ Äÿÿã×ÿÿï8<õÿÿ¢PäæÑ ÆÿÿÎÛÿÿÈ Høÿÿôççîþÿÿœ ÄÿÿêUrùÿÿÀ <õÿÿ¢ ## ÆÿÿÎ\øÿÿ¤!àÿÿ²(#uþÿÿe Äÿÿþ÷ùÿÿÿ<õÿÿ¢ Æÿÿ¨äÿÿöS ºÿÿÈ„ÿÿî4 Äÿÿÿÿÿÿÿÿ¾"<õÿÿ¢ Æÿÿÿÿÿÿÿÿ÷Š …ÿÿé+°ÿÿÌ Äÿÿÿÿÿÿÿÿÿ§ <õÿÿ¢ ÆÿÿÿÿÿÿÿÿÙ)OúÿúNÔÿÿž Äÿÿ÷¸ÍùÿÿóF<õÿÿ¢ Æÿÿ÷×Ôäþÿÿ© $âÿÿw2ïÿÿk Äÿÿã'™ÿÿÿ‹<õÿÿ¢ ÆÿÿÒ$+¹ÿÿõI ºÿÿ¢aþÿñ9 Äÿÿã!4íÿÿµ<õÿÿ¢#$ ÆÿÿÎQúÿÿ„ŠÿÿËœÿÿÑ Äÿÿã!ÖÿÿÅ <õÿÿ¢çéƒ ÆÿÿÎ7òÿÿ¤Vûÿðàÿÿ¢ Äÿÿã!ÐÿÿÐ<õÿÿ¢¯ÿÿ’ ÆÿÿÎ>õÿÿ©(æÿþþÿÿk Äÿÿã!$ãÿÿÆ <õÿÿ¢¯ÿÿ’ ÆÿÿÎxÿÿÿ” Àÿÿÿÿñ9 Äÿÿã!cûÿÿ²<õÿÿ¢¯ÿÿ’ Æÿÿä}réÿÿÿoŒÿÿÿÿÑ Äÿÿï†rŒäÿÿÿ‚Hvtr•ùÿÿÌtttm¯ÿÿ’ Æÿÿÿÿÿÿÿÿÿè1Vûÿÿÿ£ Äÿÿÿÿÿÿÿÿÿì:¡ÿÿÿÿÿÿÿÿÿÿÿð4¯ÿÿ’ ÆÿÿÿÿÿÿÿÿþŠ*èÿÿÿr Äÿÿÿÿÿÿÿÿþޤÿÿÿÿÿÿÿÿÿÿÿð4¯ÿÿ’ ÆÿÿÿÿÿÿÿëÆÿÿô? Äÿÿÿÿÿÿÿî¤ÿÿÿÿÿÿÿÿÿÿÿð4¯ÿÿ’f†„„„„„n4U†…uf†„„„„…r8U†„„„„„„„„„…|¯ÿÿ’¯ÿÿ’¯ÿÿ•¯ÿÿṺººººº»¨¯ÿÿÿÿÿÿÿÿÿÿÿè'¯ÿÿÿÿÿÿÿÿÿÿÿè'MqpppppppppqfÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÀÿÿÿÿÿÿÿðÿÿÿÿ¿ýÿðü@øÁðüðÀðüðÀðüðÀðüÀðü Àðü Àðü Àðü €Àðü €Àÿü €Àÿü€Àÿü8€Àÿü€ÀÿüÀÿ Àÿ Àÿ Àÿ Àÿ € € € >€ ~€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(€ #.#.  ¢ÏÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌΤ ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍ ÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍlŠˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆÔÿÿÿÿÿÍ£ÿÿÿÿÿÍ£ÿÿÿÿÿÍ£ÿÿÿÿÿÍ£ÿÿÿÿÿÍ£ÿÿÿÿÿÍ£ÿÿÿÿÿÍ5TRRRRRRRRRRRRS9 SRRRRRT0CSRRRRRO3TRRRRSJ RRRRRRSFRRRRRRR£ÿÿÿÿÿÍ£ÿýýýýýýýýýýýýýñЃ&Rùýýýýýÿ¶'äþýýýýþå(ÿýýýýþã"ÿýýýýýÿº aþýýýýýûU£ÿÿÿÿÿͤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþàk&åÿÿÿÿÿÿØJøÿÿÿÿÿÿÁ  ÿÿÿÿÿÿå#ÐÿÿÿÿÿÿÿvbÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóp ½ÿÿÿÿÿÿð7sÿÿÿÿÿÿÿŽ¡ÿÿÿÿÿÿå#9ðÿÿÿÿÿÿì4bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôd‰ÿÿÿÿÿÿÿ_ ÿÿÿÿÿÿüW¡ÿÿÿÿÿÿå#|ÿÿÿÿÿÿÿ¼ bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ#SûÿÿÿÿÿÿŒÈÿÿÿÿÿÿç*¡ÿÿÿÿÿÿå#ÁÿÿÿÿÿÿÿvbÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…&åÿÿÿÿÿÿ¶(æÿÿÿÿÿÿ ¡ÿÿÿÿÿÿå#9ïÿÿÿÿÿÿì4bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ ÅÿÿÿÿÿÿØIøÿÿÿÿÿÿŽ¡ÿÿÿÿÿÿå#}ÿÿÿÿÿÿÿ¼ bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ䡟ŸŸž³óÿÿÿÿÿÿÿôA˜ÿÿÿÿÿÿñ7sÿÿÿÿÿÿýZ¡ÿÿÿÿÿÿå#ÁÿÿÿÿÿÿÿvbÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸^ìÿÿÿÿÿÿÿmaþÿÿÿÿÿþc ¢ÿÿÿÿÿÿî4¡ÿÿÿÿÿÿå#9ïÿÿÿÿÿÿì4bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸ˆÿÿÿÿÿÿÿ™1íÿÿÿÿÿÿÛÄÅÅÅÅÅÅÅÅêÿÿÿÿÿÿÌ¡ÿÿÿÿÿÿå#}ÿÿÿÿÿÿÿ¼ bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸0ìÿÿÿÿÿÿ­Êÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¡ÿÿÿÿÿÿå# ½ÿÿÿÿÿÿÿvbÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸ÉÿÿÿÿÿÿÏ™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿe¡ÿÿÿÿÿÿå#+æÿÿÿÿÿÿì4bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸¿ÿÿÿÿÿÿÐbþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿî4¡ÿÿÿÿÿÿå#jÿÿÿÿÿÿÿ¼ bÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸¿ÿÿÿÿÿÿÐ1íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌ¡ÿÿÿÿÿÿå#±ÿÿÿÿÿÿÿvbÿÿÿÿÿÿþV£ÿÿÿÿÿͤÿÿÿÿÿÿ¸¿ÿÿÿÿÿÿÐÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœ¡ÿÿÿÿÿÿå#+æÿÿÿÿÿÿí4bÿÿÿÿÿÿþV•íééé뼤ÿÿÿÿÿÿ¸ Âÿÿÿÿÿÿº ™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþe¡ÿÿÿÿÿÿå#jÿÿÿÿÿÿÿ¼ bÿÿÿÿÿÿþV('''( ¤ÿÿÿÿÿÿ¸#âÿÿÿÿÿÿbþÿÿÿÿÿþñîïïïîõÿÿÿÿÿÿî4¡ÿÿÿÿÿÿð}ghÄÿÿÿÿÿÿÿvbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿ¸Yúÿÿÿÿÿÿz1ìÿÿÿÿÿøe,///.£ÿÿÿÿÿÿÌ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì4bÿÿÿÿÿÿþV¤ÿÿÿÿÿÿ¸ÇÿÿÿÿÿÿôCÓÿÿÿÿÿÿi´ÿÿÿÿÿÿ›¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ bÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÑ]YYYXb½ÿÿÿÿÿÿÿ¿¥ÿÿÿÿÿÿ˜Ùÿÿÿÿÿþd¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäTbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÿþþþþþþÿÿÿÿÿÿÿù[nÿÿÿÿÿÿ¿ 8ñÿÿÿÿÿî3¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèVbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýœ ;òÿÿÿÿÿæ(_ýÿÿÿÿÿÌ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿä9bÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø›ÓÿÿÿÿÿøJŠÿÿÿÿÿÿ›¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ® bÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ ¥ÿÿÿÿÿÿu¶ÿÿÿÿÿþd¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóJbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜCnÿÿÿÿÿÿ¢Ùÿÿÿÿÿó:¡ÿÿÿÿÿÿ󘇈‡‘Íýÿÿÿÿÿÿÿ¡bÿÿÿÿÿÿþV¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ@;òÿÿÿÿÿÉ9ñÿÿÿÿÿסÿÿÿÿÿÿå#“þÿÿÿÿÿÿÜbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿðÉÈÈÇÏõÿÿÿÿÿÿÿ»Ôÿÿÿÿÿå(kÿÿÿÿÿÿª¡ÿÿÿÿÿÿå#ÆÿÿÿÿÿÿøIbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿ¼ T×ÿÿÿÿÿÿøV¥ÿÿÿÿÿùJ•ÿÿÿÿÿÿs¡ÿÿÿÿÿÿå#eýÿÿÿÿÿÿjbÿÿÿÿÿÿþV¤ÿÿÿÿÿÿ¸Dìÿÿÿÿÿÿ©nÿÿÿÿÿÿu¿ÿÿÿÿÿô?¡ÿÿÿÿÿÿå#+êÿÿÿÿÿÿ–bÿÿÿÿÿÿþV¤ÿÿÿÿÿÿ¸¦ÿÿÿÿÿÿÙAöÿÿÿÿÿ¡!àÿÿÿÿÿסÿÿÿÿÿÿå#Öÿÿÿÿÿÿ¡bÿÿÿÿÿÿþV &''''& ¤ÿÿÿÿÿÿ¸mÿÿÿÿÿÿð2ÞÿÿÿÿÿÅQôÿÿÿÿÿª¡ÿÿÿÿÿÿå#¼ÿÿÿÿÿÿ¡bÿÿÿÿÿÿþVHâêééêß4¤ÿÿÿÿÿÿ¸TýÿÿÿÿÿüW³ÿÿÿÿÿè›üÿÿÿÿÿs¡ÿÿÿÿÿÿå#¼ÿÿÿÿÿÿ½ bÿÿÿÿÿÿþVN÷ÿÿÿÿô9¤ÿÿÿÿÿÿ¸Týÿÿÿÿÿÿc~ÿÿÿÿÿøØÿÿÿÿÿô@¡ÿÿÿÿÿÿå#¼ÿÿÿÿÿÿÄ bÿÿÿÿÿÿþVN÷ÿÿÿÿô9¤ÿÿÿÿÿÿ¸TýÿÿÿÿÿÿcIøÿÿÿÿÿþÿÿÿÿÿסÿÿÿÿÿÿå#Úÿÿÿÿÿÿ¢bÿÿÿÿÿÿþVN÷ÿÿÿÿô9¤ÿÿÿÿÿÿ¸pÿÿÿÿÿÿÿcÞÿÿÿÿÿÿÿÿÿÿÿª¡ÿÿÿÿÿÿå#9ðÿÿÿÿÿÿ¡bÿÿÿÿÿÿþVN÷ÿÿÿÿô9¤ÿÿÿÿÿÿ¸¦ÿÿÿÿÿÿøL³ÿÿÿÿÿÿÿÿÿÿÿt¡ÿÿÿÿÿÿå#pÿÿÿÿÿÿÿ“bÿÿÿÿÿÿþVN÷ÿÿÿÿô9¤ÿÿÿÿÿÿ¸8æÿÿÿÿÿÿï0~ÿÿÿÿÿÿÿÿÿÿô@¡ÿÿÿÿÿÿå##ÏÿÿÿÿÿÿÿebÿÿÿÿÿÿþVN÷ÿÿÿÿô9¤ÿÿÿÿÿÿ½PËÿÿÿÿÿÿÿØIøÿÿÿÿÿÿÿÿÿסÿÿÿÿÿÿç1G¿ÿÿÿÿÿÿÿñ9 lÿÿÿÿÿÿþa N÷ÿÿÿÿô9¤ÿÿÿÿÿÿòÒÑÑÑ×õÿÿÿÿÿÿÿÿ·Þÿÿÿÿÿÿÿÿÿª¡ÿÿÿÿÿÿú×ÑÑÑ×õÿÿÿÿÿÿÿÿËHÑÑÑÑÑÑÑÐãÿÿÿÿÿÿÿáÐÑÑÑÑÑÑÎ?N÷ÿÿÿÿô9¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþl³ÿÿÿÿÿÿÿÿÿs¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ†YþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûMN÷ÿÿÿÿô9¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß$}ÿÿÿÿÿÿÿÿô@¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã-YþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûMN÷ÿÿÿÿô9¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüvH÷ÿÿÿÿÿÿÿß ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ†YþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûMN÷ÿÿÿÿô9¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ'åÿÿÿÿÿÿÿ¶¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·YþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûMN÷ÿÿÿÿô9¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý»& ¾ÿÿÿÿÿÿÿ€¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý½'YþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûMN÷ÿÿÿÿô9¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÞ~‹ÿÿÿÿÿÿøK¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë„YþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûMN÷ÿÿÿÿô9”êæææææææææææçØ¶y%PäææææèÍ ‘êæææææææææææçáº{4PææææææææææææææææææææææææãFN÷ÿÿÿÿô9$$$$$$$$$$$$$"$$$$$$$$$$$$$$$$$$  $$$$$$$$$$$$$$$$$$$$$$$$# N÷ÿÿÿÿô9N÷ÿÿÿÿô9N÷ÿÿÿÿô9N÷ÿÿÿÿô9N÷ÿÿÿÿô9N÷ÿÿÿÿô9N÷ÿÿÿÿú¢†ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆN÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï/N÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï/N÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï/N÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï/N÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï/?ÅÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍ¿& ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿüøÿÀðøÿ€ÿü8ÿÀðøÿ€ÿüÿÀàøÿ€ÿüÿÀàøÿ€ÿü ÿ€àøÿ€ÿüÿ€Àøÿ€ÿüÿ€Àøÿ€ÿüÿ€0Àøÿ€ÿüÿ€0€øÿ€ÿüà0€øÿ€ÿüð0€øÿ€ÿüø0?øÿ€ÿüøp?øÿ€ÿüøp?øÿ€ÿüøpøÿ€ÿüøpøÿ€ÿüø€ðøÿ€ÿüø€ðÿøÿÿÿüø€ðÿøÿÿÿüð€<ðÿøÿÿÿü€<ðøÿÿÿüÀðøÿÿÿüÀð?øÿÿÿüÀðøÿÿÿüÀðøÿÿÿüàðøÿÿÿüàð€øÿÿÿüàðÀøÿÿÿüàðàøÿÿÿüðððàøÿÿÿüðððàøÿÿüøððàøÿÿüøððàøÿÿüøøðàøÿÿüøøðàøÿÿüøøðàøÿÿüðøðàøÿÿüðüðÀøÿÿüüðÿüüðÿüü?ðÿüþ?ðÿüþ?ðÿüþ?ð0ÿüþðpÿü?ÿððÿüÿððÿüÿÿððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰PNG  IHDR\r¨fGIDATxÚíÝk°]eyÀñÿÙ'rIL Hƒ\Tä6" "¢ v¤­t¦¶ÓÛ8mgZ;øÉS,ÒΔiµ­”zIDÛ¢ˆµ ‚Â¥T¢‚€Üä !Hr.ýðœ39ÉÉÙ—÷]{¯½öúÿfÎDœ³Öy×Ú{=ë½>/H’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I}fh·ÁxÙªbÖÄ¿—£e(Ó(ðçÀýeDª‚Ép(pNÙ…)ÀpuÙ…ª¢Qv$•Ç Õ˜@ª1€Tc©Æ R¤3H5fjÌ ÕØ¬Œc·¯Ñ_ ‰F€eBªŠœp9°!óÝðDÙª"çá}x¤ì ”Î>©Æ R¤3H5fjÌ Õ˜@ª1€Tc©Æ R¤3H5VÆJ¾…Àþ=þ›O[J¸Övͤ³¥ÕCÀfà™.—m°ªÇ÷ã5à1`¬ óíO|ïªnxx¶¨–Îþ‘Þnây+±rq3°xx©„kŸÉïð˜±â%D€ë–Sëzx/†€›ˆ/úzb‰÷æŒs^|ÈQe³€«&®§°öÚl`qÿæùÿŽÜ üp å× †€“€}Ž],§»`¯Ä²åX |Œø¼~øð=àzàGt¾‰í<¢&3æy²ºõ _æs€¾ \@¹_Ž×k¼µÄ²wÛäçõà“À7KŒê|_¨[˜jðNà À?‡_¸^;˜Ø9Å0Q{¨ƒpð7D“d å|^¥Î`Ò\à½ÀÍÀ‡è}ŽÃ“ÈkŠ ¬èq™Ë4x7ñyý~‡³xóB8ˆè`ùUzÀ)™ç8šA¨“ÆÄ5_‰A ‹7nWKÏèÑß[=ñ“c6ÑXG‹O.» Ue˜n ð;ÀÊü­#'~rÌNïAYûÕbâó: ì‚T‘`ÏNþ¬g¯‚Îs𺔷_D ë./» Uc˜Ù%t·)Ð &§ñGúH 8‡èÌU 3[ ü>°¬KçŸìWй†è¿ Zz­|”zˆd34w¯¯7×7D:Ì®39[ýýv4È{øÆ¦üôAïxøkà+™çYIqã˳€#ºt½ûXÎ2Œà·ÈOuv Õ{ÁõÜ €IŸ¾[v!&¬#rtÃ,"yFÕÝ\[À½°#°…º€Ÿwg?DzçÏãÔG3Ÿëç‰NßTk&î…š„/J»¾lM<¶A$ ɽ_ÃÀ]¾Îµt¯‰ÑKÿ‘qüþ?Ô:pê¶/g¿ùUÊ^¬Ý_Íà$y.ÿj¦N`ð­’ËЋì=Ãägêד—\-Ô)Œ¿,¹ GRÜ ÀfNb0fn£Ï†ÍM@Ù†‰ÉI½pƒ‘àyŠ™{¡zgàä„ã6ÒyßÅ¡Àáe_p6÷dBÙÐï ½³†´I:ß§óÝ‹†€7•}Á}à4¢ãU30ôÎ:Ò6Eý%°=á¸Ó).ç`U½VvúÝäTÉíÄ­Ý͇:øÝAq?éóɤMJyœHv¹ðÛ»’q(tõXÅ|‰´àY“à‹ÄTÙN–»>Vvá3®·S£Ä¾t©æg%÷ 1'þ¥„c –ØÖ9<_vúÝäñ,î9Þ§#¶&/ÃA¤í°»žhÿ?L¼É:mÏ®%×H{T§>€ä%sÈ '“¶qÅäß¼x!áøwQíN°98·«ê."}ð{ÉN™B¼ xbâ“6!f ½Ùá¨[ Þ»u]]Àb1OªGHO6´¬DÉLžfgv›N¬¥w“TAu ?"½*¹ø×Œ¿?›´êÿ8;ƒÎ‘å(E•«Ð’Þ„ÙŒ€- zX@ìûQÒWòýð@FNN8îFàSþûiÒ†^ßG #VÑù¤7Ûî~Pöô»A ‰ =n~ô‡ø,ip“VYz”]›ß -MÖBº·½Y7­"¯ý?µ¥T-gÚ…Äp^«´à+€·’ß~ñ&N5´,²¯1½úšú…>ŠXü¥Ì{Ñk“—Ñçi\IØRÕÀÚ‰Ÿ^>GÞÛÒåüøönÿßsÀ-À¥ çëÅä"G4ÛRk¨ãD¨ÜLÀoP›Eø:yo€·‘6ÿŒé_ÞíÀËq10·Ð»Ó={LÞ¦¬/c"‘¶ölð1òÞþÍ•y Ç}›=ç/¼ x1á| (v#Òn9ŽHz~æyîî,ûbª jM€^Ø@,¼ÉÍK?85ñØØsûõ!bjp§3×ÉH¿PØ]jÏ0‘œdœæ;@lë}Ådò½ W¶Å°« ÄÃÿtçšGÚn½#Ìœ½x„]‡Û5D9Kƒ±³-ÞloÀ½ˆÑŠ"l%v„R ;Ýü.Å<üÙhR†ß~ÈôÀI/“’Rv+~Qhµ­Z‘†èýŽÅßÄñÿ¶Ù°Óà÷&z#i“XFhž¼ôÕÄòœ@u'µë"‚Õÿ6vZ\MŒ—œy®¹¤§äº“æà>ÒšûQü–äýæ&úg ¸J0ìjp.ð÷äE¤'¤¼æã×÷¶aÆr¢V2¨|û'0ìÙÙDH]Hs imß1Z§°#}ƒu f¿Ï8p;WOªM€™M¬H™E÷Òú¾Óâw^$vÌIq*‘žlÐÜ üæÿ똠¹3é|-ÿb [h/øK‰ç_B÷¶&/Ë}Ä´áGË.Hšk¿Agµ€e¤ïÍ÷eÚ«Þ?LÚNÇûÛ† ŠûˆÕžË.HUU­=ø¿Du¯å½ãÄÃxiËq'½‰¨\ÓæïNz5»ÝνïéÂRjG3ôª¾PƇ¿U 7Ÿèà÷çÕø+Iß*kˆ¨bþíM>ƒ´y÷/Ovðû©K]ß1Q¾”5ý`;1Üw9>üÙ½ ð ð5¢Ÿ“ÿWhoöÝÞ¤n"²µc3éiÊ«3îEÙö"Eùð`ÐÀ¤ÛˆUf©b†÷Ӻ鱒´ @H([ê”å•T;Óî1Ç"§Y§ u EÞúþi}¿RS|•Î&±EÚŒÂ~°/ñ9>TvAª®N¢#ïã¤uÒ-^×âwVÍ…Ÿ¤óf@êßšG v;ì zë·±kíhœ¸Ÿ©k&›û>+RÔ/l%¾ôÝÈŽ³‚¼¶uêÜb%‘¬4'Ýy;¶9 7ív};ˆ ëIo6 JÌžT¢*·S< |+ñØñÏdù«{iy}íÚAÌ9Ø>ågœhŽå<¼‹ˆåÛÊP·䥊¾¸Ž=oÐq½O~‘ãà/Ÿ—ô÷Ÿ$j ©)ÀĬÆÙ¸â»wp‡Ç<[Ç£Ùý:’jÔ¹D;¼¬0Fä^¸˜ôšèYÄÌÆn7eªàíÄË©]ÃÀUuktËrª7Ç~%p^Ée¸ŸH–j!±jSñò™ßÁÏ`o@1–o¢ª){˰ÇÉ{{7ˆ ÊHx: Å8™j®³¿€¨ ”eœHTš³0é ?ÕY׊qÕ| ͧ¸$¨©$† S-"V|* ß2ª›ko?:OxR´Ÿ}©D¨Rlß0äÛ´ @úÅÒ² @4F2Ž;Õ Â¥ª[Ø—âw>Žj¯L;Ÿ´ L‹ôÄŽÈ©êPÝÀJâMµ‘éoªSˆÉ(Uµ˜ò;0!‚@ª1' —Ó©BÝÀ1¤¿­Ç€[vûÿ!ÉærÊï€X4”ã"q‹:P§°¸ŒÈÚS”ÕÀñe_X–—]"Í×+Ç/N,û"ª¦N=§ç’ž­¢°ûxõZÒ«ÿOY¤f)šjœ˜žºù¹D”NríàVb•bŠ;wuªzÂÓž©K8¸‚¼·ÿ]LßuöÒÀFà#."=,%r”iqSÀ›‰Ä-w•|-•1èM€1ÛíZò{ºwß´c°*ã|9«g:_j0YFܧ²ÝH^3`)雲ÖRÕj‡Õ¼v{{ßC|±‹ë~˜]«–‡[€¥%rõöø>QN"m ´¢=D^3`ˆøÌ?‡Í€¶T-|€ÈÎÛ®¢^ŒéĦ:˜ôû7ü¬Ð;û ¤l>iå§ØÚJä\ÌiÍ€¶U± 0ÔÁOQîfzú÷’Þþžôýýf2J¬®Ku&ý±_ÀÒ¶=›´ŒjC@6íT9æŠOb1Jú®ÁÁ,§O£(?&öqH5Dtˆ:)¨ €ÖFˆöúTkÈK2N±íÿ©çMµ€þè|™üêû±X h‹ µ{ˆMI§ZBú¨Â(ðõ.•u#y‰6—ÓÓš× Õ ÚÛÊ­ö ͽ\MlÀ1Õ¹D‡YŠòÖ¿7óy9þÎ&Rm—íàöÌs\Bõ:¹{ÎÐÜõDâÊÝå¬(ÜBÞXw3ãLï«èÄÞ´Þü¤¶ß xÖZ2Ìì9à³LoWFÞë¿é^ÛQ"`¥ö̧³aÖnú*yÚ+qqPK€=Û ü 1ü·»•ämL9Bñ³§šÜx#ÕRú£êü(pgæ9>Hôiô-Àt›‰ý?Ïž¤ÓHÿRßírù7Ci©Î¦?2ÿ‚ék/:µ–ôGjÁ°«É‡ÿZf~‹æ,ÿÝN÷g¨= <–qü"sR?¸žøLRíÃMvšúðÏTE?„˜êUb¯¼n'o&Ý<¢½lɼ€Qlˆbˆ‡òfà7¦yûübPªï0}NAÑÆˆ$›9ý KéïÆOodžc Åçýð!—eòÁ¿”˜:ºžÖ+ÈN ¯ƒlyÙoÛõ2ygGõ œí¸ x-ãøŒ¬M]ѽ½½2J</é§n™ø·Ý¡¦é 7 ÞÈ3ŽïÄãD_@ꤞùôO?ÀmÄD¬3Îña¢VôjÙÓoÊ?®¡;ságÒ ¾D“SL§óõâãDuôg Ço±œÅ:øðib¾Bʺø!bº3D5üoϱ•¼±|ˆÔiŸ Ò~§\Ë0Ñ)š› çó&o“$5u;™µûseû¤Ú3H5fjÌ Õ˜@ª1€Tc©Æ R¤3H5fjÌ ÕX–KEXE,—îåjÖVFHÜ¨Æ uæ àw«±²5€•] ©b|f$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’¤núÎ@Ï*â¾IEND®B`‚bart-0.5.00/packaging/bart.icon.in.rc000066400000000000000000000000671353046746100172760ustar00rootroot00000000000000id ICON "@CMAKE_CURRENT_SOURCE_DIR@/packaging/bart.ico"bart-0.5.00/packaging/bart.png000066400000000000000000000204641353046746100161250ustar00rootroot00000000000000‰PNG  IHDRôôËÖߊÜzTXtRaw profile type exifxÚíšWv世Eÿ1мìZ=ƒþÛ ÙTfWW½¿×©*…D1Hàšc.Ãìÿùïcþ‹Ù‡jb*5·œ-ÿb‹Íw~¨öù÷¼:ï÷ûïÄ×OîëqóþÏkà5<Èûyuãéã %¾Ž¯ÇM™Ï¾¾.ôú¾ÿ‚_çÕ×…‚Ž»×尿Þ×ã§í¼þ÷ó}ϵ¿ý ÁX‰ëoü.X¾GÝ%°‚PCçUß]h^G?Çï÷ösìÌûß‚÷þÓ·ØÙþ:¾†ÂØü:!‹Ñë¸Kߎ‡÷Ûø/+rwþò‡X\±Ÿÿ}ŠÝ9«ž³ŸÝõ˜‰T6¯M½måþĉƒK…û¶ÌWáÿÄÏå~5¾*[œdl‘ÍÁ×4®9O´‹n¹îŽÛ÷uºÉ£ß¾ðêýôá«¡øæçMJÔ—;¾„–!;>L²8ìß×âî}Û½ßt•;/Ç™Þq1Ç;~ù2?ü;_ï:G¥ëœ­ï±b]^5Í2”9}ç,âÎ+¦éÆ÷~™Ouc?%6ÁtÃ\Ù`·ã¹ÄHÂÍsà¼d£±Ok¸²^ DÜ;±*::›]H.;[¼/ÎÇJ~:+÷!úA\J~9sÈM™äT¯{óžâî¹>ùç0ÐB"-RHM dبŸ+5ÔSHѤ”r*©¦–z9æ”s.YÕK(±¤’K)µ´Òk¨±¦šk©µ¶Ú›oK-·bZm­õÎM;—î¼»sFïÃ0âH#2êh£OÊgÆ™fžeÖÙf_~…Eû¯¼ŠYuµÕ·Û”ÒŽ;í¼Ë®»í~¨µN<éäSN=íô÷¬½²ú5kî[æþœ5÷Êš2ïyå#k.åíNp’”32æ£#ãE  ½rf«‹Ñ+sÊ™mž¦Hž¬¹¤ä,§Œ‘Á¸Oǽçî#sÌ›Iñÿ”7ÿ»Ì¥îß‘9£Ô½2÷kÞ~ÈÚê—QÂMºP1µálœ°k÷µ‹“þö«ù§ø¿Ðhê()ïYG°•2+uy€±#&J½–V}2WW,'ûVÎ8¶ÀWÑ“í•ë© úŠ~qtA᳜#ñ“}ŸY÷qo3ïïs?\+V†v Òz:ûL@›f£^BüvÌè`J[iž>ÙnftE›çSfE‘Ç$ý·߽šÿí„¿òêFØÆß}7;àÌ“ífßüN@kïÐ∧â}…Ž\°ÂÜ»o¨´üàcíÁ4·™öj»¥pãkí·ßø69œã]Uç ›v¿·í±#÷·ö·c¤˜|‰ù“xì]ô¬™Ì=ÀD147‰ÍªŠ]m[Àr7þ¶mmúÙsÖVKcœ Tº±)SðÖ.€i~¿7w }” 6[]ãý-ð¶|CŽ„ÝôSvQK_.zÃÕ¤-& òÃh‹ô§ÂÒ+ö@ 9øžÓH -4‚„Û›‰ tB„­ÍtÉÞŠßi¥Ê: †mHûœDËg®”Ëê.VÑýn A6»Û–òê`7ËQn£T¡½#T¸fnSØM¼=gÎãò†œ¬Û3Jd„Ð\K®Yˆ'%‚äëž½p VBtÔ3gItW¼0²Ø^3®œúâp,Ôï|r%Ïó\õW£6J®Úˆ–FÑ_›fQà“~„(´À¾X“…¬ÝÓ¢~&ªÎ%ZÒ¦;´jç‡dI‹ø.ödExóüGÓ¤QS8Ë ¦<¬¶G­ü˜tk’Âp[˜¼©PŸ®SgÝ6¬¾¯‰ùµÂ a.%ƒR¹ÜȱÓÂü2fg|¯jñÞW9üØL»M…§~Qž~¯¾úÙøA‰Ü^QåàáUUŸ%¸“¸îã(íÙ"vY¦&¿Ñ,‘–ÿX¯nòkÄÞl‚£Á»1ú†Š~º4ê>#ð‘ä¼nҢNJ ƒÆòe’‰@úAÌIHæø^NÂìÈÿAý\ºS5éŽd>7=†d p‹˜E8bEăüe”pîÔ“Š‚ˆ”›Gá8FˆŒ BÜsÕZ¢J‡ó²¨ì>ÓÞ#‚Öl`t ïSï±íA°Ê±ˆtÎ&p‚yhÂ䕌@Ù]¬; ªšÓEÀô;ßèÝÈ5¨‰§ôPc _jÂtUüKaÝŸMBOê#ŸÐ\÷Fé¬Ljºß›Ñâ¯;¬fŽãŒYi˜‡‘nÀNŠV+`PF‹\+rn¬;wš,ê|<× F;ȆK±mǰVk ýIöAÏ@½)}” j:GíŠ"&K}BâM'¬>…3žËЄ ¥ð¢3wãižµ¼Öˆ{U|,aÛ%A_ý÷ÄU:žøœRn|–®òÚ¼ÑgöGÅJvp$+k 4¼¬ëNô8곿‹J t ðÝÅž¹í¦†ªßµîíÚ6мyh,@1(lùâu …JìI¨i\V¬ ©lÁ@@I¦( ˜2å`f­k4~sԆͫR“Iέ¤ig.'äqxÔKô]ÜlT«eò–5«¤e«Q!Ÿ¶°ð™Î8¼øW§×µãêeŸÐ´øCX–·™á5ÎRLŸˆîmQ hhB žÏè;ÌMÛÃ5T¡ãú IÀ3749A¬gmP¸Q‘Ó •æ(½§Ê[ >:8§Î+U™’“»@^$0l©÷1M£’Nk+TVÈHõ•`-ÞH%´dI^ç]sˆ×0±0>˜ÆÝÊÜ;QË<R+.‹ì'GWÐ Ç‚°DÆÜö&( tÖð°~GÆ7`4+—iªdCìæSó 'oã®nä·öÁn‰ÊÀÎlÁ^:T³‘àBBœ½ìBG@hb˜Cc”D*‰°…]q</¢5SãtBGH;•ªAGèŸRpk¦þúɹutB0³Ë(ÿ4Ù}0w V‰ Œ`=×fÛ´HDŒàÂ Õ bÑ8 4%1À XQ‹»? þé¶è˜ïà,÷B78¼[_£‘ÀnM klG:X¶E0=Xœ„ßÇá"AÀ-$´³ x@„W`3·ÎGµæ¯*Ê“X Ôn K+M45ÆÖAÂ^®B«+Ð!ô 8o…[÷2'jàA`ò˜™Æi}Uxjj,…kÏ'—ä’ˆÓërX®7×½`,FLæÀZ}Nð:ÄÌ¢&X~D;CyÀ˜Æ`0;–œ7Ö÷‹2—þŒ A 'Ab:)Ù´û³÷厘ÖXX„|x/&Š8B¸wÈD‹¤ …"Ýb, Š$"EÕ¸iA"Ä ÔX ÔŠ ¨@ $ÁÆÉUT¤_’šÏj0€­Êì¿a8¸m­­ûFYî ²KQ¡b¦Õ@’õí‘˨fÈ}†ÉÕ–Ìn˜èŠ}ÝѤ6Qç6е4?ŽP`IγÆv#’(ú0Y‡ÐudSÍ ]ÈyI8wp{³ü´å‡¤jæ¦eàÅ•!k‹Øñ’YÊ’<X2˜½giØ(ˆÍLù)¶Ž–oÔ\a«„Ê;‹)(}êۃ娕"EÁñŽaجþs¨ææd£‰ :_œyòB5_µuÚMªgä¹£M¤JÐ. ¬Îl⎪¥'µ7êÐ¥6:ÐO¡"I²¶Æ “·œEãb ‚=½A/(êÂv© Ð>œËÓ{K«sn`«¢¦)…I0sé¹à޶ OÁyÄ;úÑQe¼¿&àÍž%`©’RÏÄaÇ‚ÂïzYI`ÝÁÏ5-öHk.ƒæDã\ï<@w‘ÇVA=¹CE:\m«tïC0Æ¡´áNzåÈd·(Š·£RAà¤nÉH-оb+¤:÷* T£í6m”È&1 Z¡A&°ûZp|¹À{Æ|éšEbÑ=ý*%‡¨¯ $%å+¦#>ÍtÑÞ®K# Dó… Qd”è9Qº„S=<$"‚ï©l‘¯Ópå²a Ä£Ÿ·‡ýÙ‘¦À¾8Pš½Y ¡NØ©¥J"‰?R³RG¤`À¤MÞ¬½ót"­aŒÃG ò×(ÀËÌšŸµ¦’„ÑEØ"&úYJ@Uq2nƦ×Vq:® A€Ö NwvnK8eÙL³`E1 › ÎlÐWˆxô°`.µê¶ÓÈ’$k?׬›d¸_z44Ji(î§eðÂùÊ®ÎÇòù7›ýöjÞ}÷ãÑ_{¿º’ŽGGÍþù óØøT$5‰)ÌKå!w¤´ Áqz’çhȼPñÖ‡¦°}<4Mˆëœ{‡1ž«c‚¸8d1ÜÞìµôuÁ'—4úßH’£Åf1ëɽ‰HøåìçÅ(%‚WŒ¥`õ¯˜! ߥ nS²²×ü5xÐ’^CWbÀ« u»-9ÁáFÙ-—ñ5h!¹ÕØYnÙfFTiѨçBìhÀÁ&'^ñ!aˆ"xBÚÒÕÖøK.½68‡uÀ†¢Uțà ʻå“à Ðwl°æF)ÑjTÖ¦nAÆÞÆÏKC@ãE]¨.Ð)à ô C„n#ŒP6¢˜5ù£¹ùTã5€q‹5%LÐe’ï$Dfapq zz¼Á9|OCÕg›A¡FÔ¾'sõ>@›+ ëíH‘Êû鉌"ïÇ$s˜ç `n‘ÃBÝ&²ŠdCª@†süxj2Kj0}€ø”#ïSŽ˜t¬E°0}»j%kîP@¯ÂÀŒÄ'Ä^E(.ádƒf§{am/jEJ;ÜHEë0®ÌdDçš×ª®{§dq5’088ª‹¥j!3ü æîhѨeôn,Ñtp¯²"Œ¤,°S  L¨[ß¶v#|(›&јÄMÜç~`³9ïÐüLÒô|à+4kˆûg$×/È IÃ?ǰ߅?À"{'Eclj¹k9š—Þ•€’<2r¦¨€Ö*¦…à¸ašø*¹ÝI‚;íÒëÅxï#*Þú‰žY×|„N{« 3ög³O\]ðÅÔ­'ñ0(ÍŠ}À±8éû4Wk¡i,åÕ„D ;†98ÃkX¡hì>~AUŽ|ÿË'\}þ*`}‡UóWÒÏ¿AÖoÀÊŠ~ž~~ ë磟¦æ§ñÀÐh2Œ¸+èj4Œ³ &bse „ÀòÂnÇ`ÇÑTp p™WtÇ@ût–\‚êÑjVb"pØQâÆ*ãôWj­LO?±Gl£Ï$g ÐhEØ·no¶pÒ”OÚš?êylf4¥s›<”¿ÉHúMÏû# Úâìi–„Gîi@VQ‡Fñ5˜’={MZôܰf:| Ø8³çl¨éJ*„7î=jiQ?(n ËaV ð •ÀP=8!f^:¢„û8µhDaš×Õ‰Î÷ R®cN1Ÿšl&œ$Ú†ŠÖœ÷¯ÈŠÙ…j¦gõäTŠÚ“…²hê]CaE¸¯KÆ«E>øh¼ºŽãd üüžUÇ’ŽQîƒÆcui¢YV\ÒÅè_ìŸçœ†Õ&MbÓ5< +² U'†ƒ¸úŽpØEέP‚u;H …``Š„¤!àX_È·U`AŒˆÚì=Ã)»EM ùÐû€%¡†;5‰ÖuFšàhà„Gj ­A†¤Užz}ïŸô1"Ãík?3Cú @Ð úÉÀá”ÆùyÀ%ä™ú|ÕÏÇY*¨ì4Kão! xŽFËË ¦V.¿‡Ð–5¼|îîUžço¤Äåû´ih¶KŒöa»«k!õÃã-ê=¡NyÒtžG`þèèžîN·æHϪN…ñ°ëÈP`…{ûspZ„{PþæxLãiâR4JH%Ò–0cb£â´º)PuéI(šÏ;uK× K—| ”M¢]'@T›9=ÃpÄ«Óó¸r ,Íì±-Çý[»×-Xóå*ö¹'rœ²v ¸_ô»ÍÔÉzâ ŸåKÑ”•¦­`¶»®Oó(MçA .ƒ;®M(†“÷ d^‘¨§n€¿€ØÓÉV3‹3wM†wQítUÓÃ/êS¨ƒqöSŸú¢öÎ  Yé”)í|œ¼qä5úìE‡_×#¿udz$=`ÊS) tª^ƒ< =W/°Ù¨X¶s!Ò"f°™Nngo¥%º<¾Tƒ>SAwB4€ú”%p*õhîæÙš•i¸«¦w NŠt1ë=ZžON~ŸúÃkì©9UÎx×ì»§*‚ºŠ£®ï€¡’Å`Z¢&9h-=6Ã@”·ç¿iXùÄŽ Ux°WØw¹•@¡h잙ݬ-Êh ÆŽT@× /—šFcÉÄ·ð4ð–ÌÑRÞxV †ƒL ÎW¯IƒM"Å;8¡  áU?(ꃘ%Íòç¥Ç­à@ê $GM^1nõ|ð3p›‰4° 5ÃzËjhƒH¦}š= #ì» ‚¥rQžH¢JZý¤©a¹©÷™IôºïÞ¤¥u§Rò–ˬ£Mx*»ÐuÅ "ZDd\Ùœ º‡ÏÂÃ4ÃP°DÑfÊ]E t0¾ŸåùìQccf~A€ëQ|NÖ ì~Æñs «èõD ¹V<µ©O*Á8øÑûüOB…VÊ‹¥òûÔS2í¼D(¡„¢¹Šsdj’4qC͇Î4Ñ"&'À}éPl‘Ê&˜Ñ9ßLÙŽöÌwfé±ö>{$–÷IøM²o®õ,X #üò6©ž4…nH²¥DŠlDBp6 ¨6 |ƒciº$õï•ñ•gÌ'Z´:ª$yM Ò/iÜÆ.®ìè^ É`åÐt­ý‰™L,ÏCÌç¹ç;ihkó§tZûJ(élšK&QAqU/ÈÕ@?-|+v¾õDŠR¼ø“_'ÔÞ>¶t>xí 5ÉÑÓÅ'^d›uÄP{>›A¸ž¡ âûuJöB³‡*ÞQdz½`ý­W©íÇB¸´<á9ÁUÙk¾~´?¿š¿zâ—WšÀ¢™vfÑÈæYÑØú8…ˆ^Ï™|xMþìë5”@Ùݯ„b«z Î^±Ì!K/ä¼î§9ôIѪQ wáÚà¼ñÀtè¢t£þóWÄõq"NÃúÓ'nÌ?ÿ“8È£ç±roh5}Ð×êó#…¨é6ê¸hôÚD+Ùž; u'i€®ùZÆŒ¶vÊc—îEdÓõ‡ŸŽ«ôœäŒ |QWÜXGoþ?ª+Ô•‘2h¡{?1³ek¯v==|õ #/ô() ‘íè©€ÈõÀ©z2}ÆØ÷C:íßý©±ÿ¿Ð߸ey–¬÷¿ù!É8¨Þ„bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEâ /a@ñÁ ÙIDATxÚíÜÁN#;@ÑòÿÿrÍ!±C»Ýåò9»·š¤×µ Ḛ̀·t@ÐAAt@Ð@ÐAtt@ÐAt@ÐAAt@Ð@ÐAtt@ÐAt@ÐAAt@Ð@ÐAt@Ð@ÐAtt@ÐAt@ÐAAt@Ð@ÐAtt@ÐAt@ÐAAt@Ð@ÐAtt@ÐAÝ#At@Ð@ÐAtt@ÐAt@ÐAA¸Óøþ‘I ™žNè 耠‚:: 耠‚‚: 耠€ ‚: 耠€ ‚: è 耠3Õÿ`f†ÇN耠€ ‚: è 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚:: èÀSF÷7Ùùýefø×ÿntøœº¯¥ÊŸÓ ÏÞ÷DÐEéÍBùz2"Òç²ß÷Âg†:e†’Ö‚N£d¸Ó›_Š;hù9XO:QË“Ö ÿ.>Sa¬%' °–@ÐqÂk 'ŒŠïѰ·–@Ð1ˆÀZAÇ k AÇ ¬%ƒÈû1à­%t@Ðq²k Aƒ¬%0ØñÙ#èB^?€ #Š`-!耠ãdXK:´œ: è6› èB‚€ 2‚Ž!äu怠‚P›CAdžÃëºÁ|™>Ô[O•×RDäOïuöLÙñVz‚Δ/²¸ƒµï¸r?üô'¯%ë AÇ *~ÊÙíôå´h“ ‚nMÖ’‚`ƒŒ cÖ‚Ž!TÌ®×–®[A°AFШÂM ‚îTñØ©ÂÂzA› ›#@ÐAA§?÷ë A‡íuùù³Ÿ£‚‚: èpE·Ÿ;û9z ~1AœØ8™œf¼/@ÐAn÷õ q~1ŽUß5tŽ>ÝÎìçèÀo »BpB™\ÏÞÇí èÐp³2ð6j€ € C­“*¬ævAÇà@С’ ·6l€ ;{ÏC 耠㤠€ #æø¼=ï·Ü|!è†Í1Cgå{7\AÇIí‚T1<!1°iÆ EÃÅ€Ah'tC·Íé\Ðð'tØjó‚ï:†ç‚Ó9‚ˆŽç ‚ŽS¨ èˆ9œ¸Y´Ît ™ïÛ0Þ7än~tD£O”ž!ÔâÿCg‹˜¾tþÙ<#è.ˆ0ðz½\¹#悎˜{žÖ‚Ž¡ò+®\=@а‘FÐuM£.ìàtŽ ã´¾õë¸:dWi›/@Ð p:GÐuQ§stΈº„ç$æ èÇcÃÖÐQFt1GСÐ)ÝM€ç%æ è`èâ{… ƒ¡AŽï‚ æbΆG°ßb®ôwÖïx¯Nÿµ>Ä'tn†ˆ9ºáá4mc“ #Følè¶±EЃÑó@ÐiyJ[tQÇ3ØÃंFDˆ°àïü¥¸†'BCÅœÐ't ‚N×ý/ïãÉ›S'tާ è\<Ñ è6µß¸qBÐÙš!æóáà¿å´ôôßdðÛî¬<´df8¡@‚N€ ƒàP—ßvGÐA˜èôk_×î:t‚:À4®Ýt AAt€\»#耠58!‚ cp -¸vGÐAÇéA&qåë3@Ð1, 3Zp“„ ‚ŽÓ/`­"耘LãÚŽ†G`Hw•‡·¸N蔊‚ØÌ!è6¡ ègïðíòq:Ý@özÁº@Ðq*¯¯úµªk_Ïfñ[îv݆"€::>—‡¹aBÐÁ0t°Ù°)â“ÛÀ¦ CÐÉÐɬ 7N:†Ÿ×'&€ ÏrÕë³@Ðq:7œ8ò» ‚Ž€ tçf AÇé|³×Yéu‹Èþßt@ÐqjlˆtÄ|çAÐ1Øp*›bþdv߀Ø@aƒ… #,` è`:bN ®y}:bn:NæÞC·÷á³AgñÀ2´ .·^:BŽ€€ #äB_kÆS@Ðq"l–YbxNÞkÍ÷cˆ‚.àpùDèûdƒÅfë6ÓwîÜ ¯Øtú:4 è 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚:: 耠‚‚ìbxü¯ˆHOÁ t@Ð@ÐAtt@ÐAt@ÐAAt@Ð@ÐAtt`?‘™ž8¡‚: è 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚:: 耠‚‚‚: è 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚:: 耠‚:: 耠‚‚: 耠€ ‚: è 耠‚üì;¾'ªÐ¶ ÁIEND®B`‚bart-0.5.00/python/000077500000000000000000000000001353046746100140565ustar00rootroot00000000000000bart-0.5.00/python/bart.py000066400000000000000000000054551353046746100153710ustar00rootroot00000000000000# Copyright 2016. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # # Authors: # 2016 Siddharth Iyer # 2018 Soumick Chatterjee , WSL Support import subprocess as sp import tempfile as tmp import cfl import os from wslsupport import PathCorrection def bart(nargout, cmd, *args): if type(nargout) != int or nargout < 0: print("Usage: bart(, , )") return None try: bart_path = os.environ['TOOLBOX_PATH'] + '/bart ' except: bart_path = None isWSL = False if not bart_path: if os.path.isfile('/usr/local/bin/bart'): bart_path = '/usr/local/bin' elif os.path.isfile('/usr/bin/bart'): bart_path = '/usr/bin' else: bartstatus = os.system('wsl bart version -V') if bartstatus==0: bart_path = '/usr/bin' isWSL = True else: raise Exception('Environment variable TOOLBOX_PATH is not set.') name = tmp.NamedTemporaryFile().name nargin = len(args) infiles = [name + 'in' + str(idx) for idx in range(nargin)] in_str = ' '.join(infiles) for idx in range(nargin): cfl.writecfl(infiles[idx], args[idx]) outfiles = [name + 'out' + str(idx) for idx in range(nargout)] out_str = ' '.join(outfiles) if os.name =='nt': if isWSL: #For WSL and modify paths cmdWSL = PathCorrection(cmd) in_strWSL = PathCorrection(in_str) out_strWSL = PathCorrection(out_str) ERR = os.system('wsl bart ' + cmdWSL + ' ' + in_strWSL + ' ' + out_strWSL) else: #For cygwin use bash and modify paths ERR = os.system('bash.exe --login -c ' + bart_path + '"/bart ' + cmd.replace(os.path.sep, '/') + ' ' + in_str.replace(os.path.sep, '/') + ' ' + out_str.replace(os.path.sep, '/') + '"') #TODO: Test with cygwin, this is just translation from matlab code else: ERR = os.system(bart_path + '/bart ' + cmd + ' ' + in_str + ' ' + out_str) for elm in infiles: if os.path.isfile(elm + '.cfl'): os.remove(elm + '.cfl') if os.path.isfile(elm + '.hdr'): os.remove(elm + '.hdr') output = [] for idx in range(nargout): elm = outfiles[idx] if not ERR: output.append(cfl.readcfl(elm)) if os.path.isfile(elm + '.cfl'): os.remove(elm + '.cfl') if os.path.isfile(elm + '.hdr'): os.remove(elm + '.hdr') if ERR: raise Exception("Command exited with an error.") if nargout == 1: output = output[0] return output bart-0.5.00/python/bartview.py000077500000000000000000000325061353046746100162640ustar00rootroot00000000000000#!/usr/bin/python # # Copyright 2015. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # # Authors: # 2015 Frank Ong from __future__ import division import operator import numpy as np import sys import matplotlib import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button, RadioButtons from functools import partial import time import threading import os.path class DiscreteSlider(Slider): """A matplotlib slider widget with discrete steps.""" def __init__(self, *args, **kwargs): self.previous_val = kwargs['valinit'] Slider.__init__(self, *args, **kwargs) def set_val(self, val): discrete_val = round(val) xy = self.poly.xy xy[2] = discrete_val, 1 xy[3] = discrete_val, 0 self.poly.xy = xy self.valtext.set_text(self.valfmt % discrete_val) if self.drawon: self.ax.figure.canvas.draw() self.val = val if self.previous_val!=discrete_val: self.previous_val = discrete_val if not self.eventson: return for cid, func in self.observers.iteritems(): func(discrete_val) class BartView(object): def __init__(self, cflname): matplotlib.rcParams['toolbar'] = 'None' #matplotlib.rcParams['font.size'] = 6 # Read data self.cflname = sys.argv[1] self.im = self.readcfl(self.cflname) self.im_unsqueeze_shape = np.where( np.array(self.im.shape) > 1 )[0] self.im = self.im.squeeze() t1 = time.clock() # Reorder image self.Ndims = len( self.im.shape ) self.order = np.r_[:self.Ndims] self.im_ordered = self.im self.order3 = np.array([0,1,1]) # Slice image self.slice_num = np.zeros( self.Ndims, dtype = 'int' ); self.im_shape = self.im_ordered.shape self.im_slice = self.im_ordered[ (slice(None), slice(None)) + tuple(self.slice_num[2:]) ] # Create figure self.fig = plt.figure(facecolor='black', figsize=(9,6)) #self.fig = plt.figure(facecolor='black', figsize=(6,4)) self.fig.subplots_adjust( left=0.0 , bottom=0.0 , right=1.0 , top=1 - 0.25) self.fig.canvas.set_window_title(self.cflname) # Show image self.immax = np.max(abs(self.im)) self.l = plt.imshow( abs(self.im_slice) , cmap = "gray", vmin=0, vmax=self.immax) self.ax = plt.gca() self.asp = self.im_ordered.shape[1] / self.im_ordered.shape[0] self.aspect = 1 self.ax.set_aspect( 1 ) plt.axis('off') radios = [] buttons = [] sliders = [] # Create Radio Buttons for X Y dimensions dims = self.im_unsqueeze_shape[ self.order ].astype(str) for i in xrange(0,len(dims)): dims[i] = "Dim " + dims[i] oboxx_ax = plt.axes( [0, 1 - 0.03, 0.1, 0.03], axisbg = "gainsboro" ) oboxx_ax.set_xticks([]); oboxx_ax.set_yticks([]); orderx_ax = plt.axes( [0, 1 - 0.18, 0.1, 0.15], axisbg = 'gainsboro' ) orderx_radio = RadioButtons( orderx_ax, dims, activecolor = 'SteelBlue', active = 0 ) orderx_ax.text(0.5,1.05, 'Up/Down', horizontalalignment = 'center') radios.append( orderx_radio ) orderx_radio.on_clicked( self.update_orderx ) oboxy_ax = plt.axes( [0.1, 1 - 0.03, 0.1, 0.03], axisbg = "gainsboro" ) oboxy_ax.set_xticks([]); oboxy_ax.set_yticks([]); ordery_ax = plt.axes( [0.1, 1 - 0.18, 0.1, 0.15], axisbg = 'gainsboro' ) ordery_radio = RadioButtons( ordery_ax, dims, activecolor = 'SteelBlue', active = 1 ) ordery_ax.text(0.5,1.05, 'Left/Right', horizontalalignment = 'center') radios.append( ordery_radio ) ordery_radio.on_clicked( self.update_ordery ) # Create Radio buttons for mosaic self.mosaic_valid = False mbox_ax = plt.axes( [0.2, 1 - 0.03, 0.1, 0.03], axisbg = "gainsboro" ) mbox_ax.set_xticks([]); mbox_ax.set_yticks([]); mosaic_ax = plt.axes( [0.2, 1 - 0.18, 0.1, 0.15], axisbg = 'gainsboro' ) mosaic_radio = RadioButtons( mosaic_ax, dims, activecolor = 'SteelBlue', active = 1 ) mosaic_ax.text(0.5,1.05, 'Mosaic', horizontalalignment = 'center') radios.append( mosaic_radio ) mosaic_radio.on_clicked( self.update_mosaic ) # Create flip buttons self.flipx = 1; flipx_ax = plt.axes( [0.3, 1 - 0.09, 0.1, 0.09] ) flipx_button = Button( flipx_ax, 'Flip\nUp/Down', color='gainsboro' ) flipx_button.on_clicked(self.update_flipx); self.flipy = 1; flipy_ax = plt.axes( [0.3, 1 - 0.18, 0.1, 0.09] ) flipy_button = Button( flipy_ax, 'Flip\nLeft/Right', color='gainsboro' ) flipy_button.on_clicked(self.update_flipy); # Create Refresh buttons refresh_ax = plt.axes( [0.4, 1 - 0.09, 0.1, 0.09] ) refresh_button = Button( refresh_ax, 'Refresh', color='gainsboro' ) refresh_button.on_clicked(self.update_refresh); # Create Save button save_ax = plt.axes( [0.4, 1 - 0.18, 0.1, 0.09] ) save_button = Button( save_ax, 'Export to\nPNG', color='gainsboro' ) save_button.on_clicked(self.save); # Create dynamic refresh radio button #self.drefresh = threading.Event() #drefresh_ax = plt.axes( [0.4, 1 - 0.18, 0.1, 0.09] ) #drefresh_button = Button( drefresh_ax, 'Dynamic\nRefresh', color='gainsboro' ) #drefresh_button.on_clicked(self.update_drefresh); # Create Magnitude/phase radio button self.magnitude = True mag_ax = plt.axes( [0.5, 1 - 0.18, 0.1, 0.18], axisbg = 'gainsboro' ) mag_radio = RadioButtons( mag_ax, ('Mag','Phase') , activecolor = 'SteelBlue', active = 0 ) radios.append( mag_radio ) mag_radio.on_clicked( self.update_magnitude ) sbox_ax = plt.axes( [0.6, 1 - 0.18, 0.5, 0.18], axisbg='gainsboro') sbox_ax.set_xticks([]) sbox_ax.set_yticks([]) # Create aspect sliders aspect_ax = plt.axes( [0.65, 1 - 0.09 + 0.02, 0.1, 0.02], axisbg = 'white' ) aspect_slider = Slider( aspect_ax, "", 0.25, 4, valinit=1, color='SteelBlue') aspect_ax.text( 4 / 2,1.5, 'Aspect Ratio', horizontalalignment = 'center') sliders.append( aspect_slider ) aspect_slider.on_changed( self.update_aspect ) # Create contrast sliders self.vmin = 0 vmin_ax = plt.axes( [0.83, 1 - 0.09 + 0.02, 0.1, 0.02], axisbg = 'white' ) vmin_slider = Slider( vmin_ax, "", 0, 1, valinit=0, color='SteelBlue') vmin_ax.text(0.5,1.5, 'Contrast Min', horizontalalignment = 'center') sliders.append( vmin_slider ) vmin_slider.on_changed( self.update_vmin ) self.vmax = 1 vmax_ax = plt.axes( [0.83, 1 - 0.18 + 0.02, 0.1, 0.02], axisbg = 'white' ) vmax_slider = Slider( vmax_ax, "", 0, 1, valinit=1, color='SteelBlue') vmax_ax.text(0.5,1.5, 'Contrast Max', horizontalalignment = 'center') sliders.append( vmax_slider ) vmax_slider.on_changed( self.update_vmax ) # Create sliders for choosing slices box_ax = plt.axes( [0, 1 - 0.25, 1, 0.07], axisbg='gainsboro') box_ax.set_xticks([]) box_ax.set_yticks([]) slider_thick = 0.02 slider_start = 0.1 ax = [] for d in np.r_[:self.Ndims]: slice_ax = plt.axes( [0.01 + 1 / self.Ndims * d, 1 - 0.24, 0.8 / self.Ndims, slider_thick] , axisbg='white') slice_slider = DiscreteSlider( slice_ax, "", 0, self.im_shape[d]-1, valinit=self.slice_num[d],valfmt='%i', color='SteelBlue') slice_ax.text( (self.im_shape[d]-1)/2,1.5, 'Dim %d Slice' % self.im_unsqueeze_shape[d], horizontalalignment = 'center' ) sliders.append(slice_slider); slice_slider.on_changed( partial( self.update_slice, d ) ) plt.show() def readcfl(self, name): h = open(name + ".hdr", "r") h.readline() # skip l = h.readline() dims = [int(i) for i in l.split( )] n = reduce(operator.mul, dims, 1) h.close() return np.memmap( name + ".cfl", dtype = np.complex64, mode='r', shape=tuple(dims), order='F' ) def save( self, event ): extent = self.ax.get_window_extent().transformed(self.fig.dpi_scale_trans.inverted()) num = 0 fname = self.cflname + '_' + str(num) + '.png' while( os.path.isfile(fname) ): num += 1 fname = self.cflname + '_' + str(num) + '.png' self.fig.savefig(fname, bbox_inches=extent) def update_flipx( self, event ): self.flipx *= -1 self.update_image() def update_flipy( self, event ): self.flipy *= -1 self.update_image() def update_refresh( self, event ): self.update_image() def dynamic_refresh( self ): while( self.drefresh.is_set() ): self.update_image() def update_drefresh( self, event ): if ( self.drefresh.is_set() ): self.drefresh.clear() else: self.drefresh.set() th = threading.Thread( target = self.dynamic_refresh ) th.start() def update_aspect( self, aspect ): self.aspect = aspect self.ax.set_aspect( self.asp * self.im_ordered.shape[0] / self.im_ordered.shape[1] * aspect ) def update_vmax( self, vmax ): self.vmax = max(self.vmin, vmax) self.l.set_clim( vmax = self.vmax * self.immax ); def update_vmin( self, vmin ): self.vmin = min(self.vmax,vmin) self.l.set_clim( vmin = self.vmin * self.immax ); def update_magnitude( self, l ): self.magnitude = ( l == 'Mag' ) if (self.magnitude): self.l.set_cmap('gray') else: self.l.set_cmap('hsv') self.update_image() def update_orderx( self, l ): l = int(l[4:]) self.order3[0] = np.where( self.im_unsqueeze_shape == l )[0] self.update_ordered_image() def update_ordery( self, l ): l = int(l[4:]) self.order3[1] = np.where( self.im_unsqueeze_shape == l )[0] self.update_ordered_image() def update_ordered_image(self): self.mosaic_valid = len( self.order3[:3] ) == len( set( self.order3[:3] ) ) self.order_valid = len( self.order3[:2] ) == len( set( self.order3[:2] ) ); if ( self.mosaic_valid ): self.order[:3] = self.order3[:3] order_remain = np.r_[:self.Ndims] for t in np.r_[:3]: order_remain = order_remain[ (order_remain != self.order[t] ) ] self.order[3:] = order_remain self.im_ordered = np.transpose( self.im, self.order ) self.ax.set_aspect( self.asp * self.im_ordered.shape[0] / self.im_ordered.shape[1] * self.aspect ) self.update_image() elif ( self.order_valid ): self.order[:2] = self.order3[:2] order_remain = np.r_[:self.Ndims] for t in np.r_[:2]: order_remain = order_remain[ (order_remain != self.order[t] ) ] self.order[2:] = order_remain self.im_ordered = np.transpose( self.im, self.order ) self.ax.set_aspect( self.asp * self.im_ordered.shape[0] / self.im_ordered.shape[1] * self.aspect ) self.update_image() def update_image( self ): self.immax = np.max(abs(self.im)) self.l.set_clim( vmin = self.vmin * self.immax , vmax = self.vmax * self.immax ); if ( self.mosaic_valid ): im_slice = self.im_ordered[ (slice(None,None,self.flipx), slice(None,None,self.flipy), slice(None)) + tuple(self.slice_num[self.order[3:]])] im_slice = self.mosaic( im_slice ) else: im_slice = self.im_ordered[ (slice(None,None,self.flipx), slice(None,None,self.flipy)) + tuple(self.slice_num[self.order[2:]]) ] if self.magnitude: self.l.set_data( abs(im_slice) ) else: self.l.set_data( (np.angle(im_slice) + np.pi) / (2 * np.pi) ) self.fig.canvas.draw() def update_slice( self, d, s ): self.slice_num[d] = int(round(s)) self.update_image() def mosaic( self, im ): im = im.squeeze() (x, y, z) = im.shape z2 = int( np.ceil( z ** 0.5 ) ) z = int( z2 ** 2 ) im = np.pad( im, [(0,0), (0,0), (0, z - im.shape[2] )], mode='constant') im = im.reshape( (x, y * z, 1), order = 'F' ) im = im.transpose( (1, 2, 0) ) im = im.reshape( (y * z2 , z2, x), order = 'F' ) im = im.transpose( (2, 1, 0) ) im = im.reshape( (x * z2, y * z2), order = 'F' ) return im def update_mosaic( self, l ): l = int(l[4:]) self.order3[2] = np.where( self.im_unsqueeze_shape == l )[0] self.update_ordered_image() if __name__ == "__main__": # Error if more than 1 argument if (len(sys.argv) != 2): print "BartView: multidimensional image viewer for cfl" print "Usage: bview cflname" exit() BartView( sys.argv[1] ) bart-0.5.00/python/bartview3.py000077500000000000000000000326101353046746100163430ustar00rootroot00000000000000#!/usr/bin/python3 # # Copyright 2017. Massachusetts Institute of Technology. # Copyright 2015. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # # Authors: # 2015 Frank Ong # 2017 Siddharth Iyer import operator import numpy as np import sys import matplotlib import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button, RadioButtons from functools import partial, reduce import time import threading import os.path class DiscreteSlider(Slider): """A matplotlib slider widget with discrete steps.""" def __init__(self, *args, **kwargs): self.previous_val = kwargs['valinit'] Slider.__init__(self, *args, **kwargs) def set_val(self, val): discrete_val = round(val) xy = self.poly.xy xy[2] = discrete_val, 1 xy[3] = discrete_val, 0 self.poly.xy = xy self.valtext.set_text(self.valfmt % discrete_val) if self.drawon: self.ax.figure.canvas.draw() self.val = val if self.previous_val!=discrete_val: self.previous_val = discrete_val if not self.eventson: return for cid, func in self.observers.items(): func(discrete_val) class BartView(object): def __init__(self, cflname): matplotlib.rcParams['toolbar'] = 'None' #matplotlib.rcParams['font.size'] = 6 # Read data self.cflname = sys.argv[1] self.im = self.readcfl(self.cflname) self.im_unsqueeze_shape = np.where( np.array(self.im.shape) > 1 )[0] self.im = self.im.squeeze() t1 = time.clock() # Reorder image self.Ndims = len( self.im.shape ) self.order = np.r_[:self.Ndims] self.im_ordered = self.im self.order3 = np.array([0,1,1]) # Slice image self.slice_num = np.zeros( self.Ndims, dtype = 'int' ); self.im_shape = self.im_ordered.shape self.im_slice = self.im_ordered[ (slice(None), slice(None)) + tuple(self.slice_num[2:]) ] # Create figure self.fig = plt.figure(facecolor='black', figsize=(9,6)) #self.fig = plt.figure(facecolor='black', figsize=(6,4)) self.fig.subplots_adjust( left=0.0 , bottom=0.0 , right=1.0 , top=1 - 0.25) self.fig.canvas.set_window_title(self.cflname) # Show image self.immax = np.max(abs(self.im)) self.l = plt.imshow( abs(self.im_slice) , cmap = "gray", vmin=0, vmax=self.immax) self.ax = plt.gca() self.asp = self.im_ordered.shape[1] / self.im_ordered.shape[0] self.aspect = 1 self.ax.set_aspect( 1 ) plt.axis('off') radios = [] buttons = [] sliders = [] # Create Radio Buttons for X Y dimensions dims = self.im_unsqueeze_shape[ self.order ].astype(str) for i in range(0,len(dims)): dims[i] = "Dim " + dims[i] oboxx_ax = plt.axes( [0, 1 - 0.03, 0.1, 0.03], axisbg = "gainsboro" ) oboxx_ax.set_xticks([]); oboxx_ax.set_yticks([]); orderx_ax = plt.axes( [0, 1 - 0.18, 0.1, 0.15], axisbg = 'gainsboro' ) orderx_radio = RadioButtons( orderx_ax, dims, activecolor = 'SteelBlue', active = 0 ) orderx_ax.text(0.5,1.05, 'Up/Down', horizontalalignment = 'center') radios.append( orderx_radio ) orderx_radio.on_clicked( self.update_orderx ) oboxy_ax = plt.axes( [0.1, 1 - 0.03, 0.1, 0.03], axisbg = "gainsboro" ) oboxy_ax.set_xticks([]); oboxy_ax.set_yticks([]); ordery_ax = plt.axes( [0.1, 1 - 0.18, 0.1, 0.15], axisbg = 'gainsboro' ) ordery_radio = RadioButtons( ordery_ax, dims, activecolor = 'SteelBlue', active = 1 ) ordery_ax.text(0.5,1.05, 'Left/Right', horizontalalignment = 'center') radios.append( ordery_radio ) ordery_radio.on_clicked( self.update_ordery ) # Create Radio buttons for mosaic self.mosaic_valid = False mbox_ax = plt.axes( [0.2, 1 - 0.03, 0.1, 0.03], axisbg = "gainsboro" ) mbox_ax.set_xticks([]); mbox_ax.set_yticks([]); mosaic_ax = plt.axes( [0.2, 1 - 0.18, 0.1, 0.15], axisbg = 'gainsboro' ) mosaic_radio = RadioButtons( mosaic_ax, dims, activecolor = 'SteelBlue', active = 1 ) mosaic_ax.text(0.5,1.05, 'Mosaic', horizontalalignment = 'center') radios.append( mosaic_radio ) mosaic_radio.on_clicked( self.update_mosaic ) # Create flip buttons self.flipx = 1; flipx_ax = plt.axes( [0.3, 1 - 0.09, 0.1, 0.09] ) flipx_button = Button( flipx_ax, 'Flip\nUp/Down', color='gainsboro' ) flipx_button.on_clicked(self.update_flipx); self.flipy = 1; flipy_ax = plt.axes( [0.3, 1 - 0.18, 0.1, 0.09] ) flipy_button = Button( flipy_ax, 'Flip\nLeft/Right', color='gainsboro' ) flipy_button.on_clicked(self.update_flipy); # Create Refresh buttons refresh_ax = plt.axes( [0.4, 1 - 0.09, 0.1, 0.09] ) refresh_button = Button( refresh_ax, 'Refresh', color='gainsboro' ) refresh_button.on_clicked(self.update_refresh); # Create Save button save_ax = plt.axes( [0.4, 1 - 0.18, 0.1, 0.09] ) save_button = Button( save_ax, 'Export to\nPNG', color='gainsboro' ) save_button.on_clicked(self.save); # Create dynamic refresh radio button #self.drefresh = threading.Event() #drefresh_ax = plt.axes( [0.4, 1 - 0.18, 0.1, 0.09] ) #drefresh_button = Button( drefresh_ax, 'Dynamic\nRefresh', color='gainsboro' ) #drefresh_button.on_clicked(self.update_drefresh); # Create Magnitude/phase radio button self.magnitude = True mag_ax = plt.axes( [0.5, 1 - 0.18, 0.1, 0.18], axisbg = 'gainsboro' ) mag_radio = RadioButtons( mag_ax, ('Mag','Phase') , activecolor = 'SteelBlue', active = 0 ) radios.append( mag_radio ) mag_radio.on_clicked( self.update_magnitude ) sbox_ax = plt.axes( [0.6, 1 - 0.18, 0.5, 0.18], axisbg='gainsboro') sbox_ax.set_xticks([]) sbox_ax.set_yticks([]) # Create aspect sliders aspect_ax = plt.axes( [0.65, 1 - 0.09 + 0.02, 0.1, 0.02], axisbg = 'white' ) aspect_slider = Slider( aspect_ax, "", 0.25, 4, valinit=1, color='SteelBlue') aspect_ax.text( 4 / 2,1.5, 'Aspect Ratio', horizontalalignment = 'center') sliders.append( aspect_slider ) aspect_slider.on_changed( self.update_aspect ) # Create contrast sliders self.vmin = 0 vmin_ax = plt.axes( [0.83, 1 - 0.09 + 0.02, 0.1, 0.02], axisbg = 'white' ) vmin_slider = Slider( vmin_ax, "", 0, 1, valinit=0, color='SteelBlue') vmin_ax.text(0.5,1.5, 'Contrast Min', horizontalalignment = 'center') sliders.append( vmin_slider ) vmin_slider.on_changed( self.update_vmin ) self.vmax = 1 vmax_ax = plt.axes( [0.83, 1 - 0.18 + 0.02, 0.1, 0.02], axisbg = 'white' ) vmax_slider = Slider( vmax_ax, "", 0, 1, valinit=1, color='SteelBlue') vmax_ax.text(0.5,1.5, 'Contrast Max', horizontalalignment = 'center') sliders.append( vmax_slider ) vmax_slider.on_changed( self.update_vmax ) # Create sliders for choosing slices box_ax = plt.axes( [0, 1 - 0.25, 1, 0.07], axisbg='gainsboro') box_ax.set_xticks([]) box_ax.set_yticks([]) slider_thick = 0.02 slider_start = 0.1 ax = [] for d in np.r_[:self.Ndims]: slice_ax = plt.axes( [0.01 + 1 / self.Ndims * d, 1 - 0.24, 0.8 / self.Ndims, slider_thick] , axisbg='white') slice_slider = DiscreteSlider( slice_ax, "", 0, self.im_shape[d]-1, valinit=self.slice_num[d],valfmt='%i', color='SteelBlue') slice_ax.text( (self.im_shape[d]-1)/2,1.5, 'Dim %d Slice' % self.im_unsqueeze_shape[d], horizontalalignment = 'center' ) sliders.append(slice_slider); slice_slider.on_changed( partial( self.update_slice, d ) ) plt.show() def readcfl(self, name): h = open(name + ".hdr", "r") h.readline() # skip l = h.readline() dims = [int(i) for i in l.split( )] n = reduce(operator.mul, dims, 1) h.close() return np.memmap( name + ".cfl", dtype = np.complex64, mode='r', shape=tuple(dims), order='F' ) def save( self, event ): extent = self.ax.get_window_extent().transformed(self.fig.dpi_scale_trans.inverted()) num = 0 fname = self.cflname + '_' + str(num) + '.png' while( os.path.isfile(fname) ): num += 1 fname = self.cflname + '_' + str(num) + '.png' self.fig.savefig(fname, bbox_inches=extent) def update_flipx( self, event ): self.flipx *= -1 self.update_image() def update_flipy( self, event ): self.flipy *= -1 self.update_image() def update_refresh( self, event ): self.update_image() def dynamic_refresh( self ): while( self.drefresh.is_set() ): self.update_image() def update_drefresh( self, event ): if ( self.drefresh.is_set() ): self.drefresh.clear() else: self.drefresh.set() th = threading.Thread( target = self.dynamic_refresh ) th.start() def update_aspect( self, aspect ): self.aspect = aspect self.ax.set_aspect( self.asp * self.im_ordered.shape[0] / self.im_ordered.shape[1] * aspect ) def update_vmax( self, vmax ): self.vmax = max(self.vmin, vmax) self.l.set_clim( vmax = self.vmax * self.immax ); def update_vmin( self, vmin ): self.vmin = min(self.vmax,vmin) self.l.set_clim( vmin = self.vmin * self.immax ); def update_magnitude( self, l ): self.magnitude = ( l == 'Mag' ) if (self.magnitude): self.l.set_cmap('gray') else: self.l.set_cmap('hsv') self.update_image() def update_orderx( self, l ): l = int(l[4:]) self.order3[0] = np.where( self.im_unsqueeze_shape == l )[0] self.update_ordered_image() def update_ordery( self, l ): l = int(l[4:]) self.order3[1] = np.where( self.im_unsqueeze_shape == l )[0] self.update_ordered_image() def update_ordered_image(self): self.mosaic_valid = len( self.order3[:3] ) == len( set( self.order3[:3] ) ) self.order_valid = len( self.order3[:2] ) == len( set( self.order3[:2] ) ); if ( self.mosaic_valid ): self.order[:3] = self.order3[:3] order_remain = np.r_[:self.Ndims] for t in np.r_[:3]: order_remain = order_remain[ (order_remain != self.order[t] ) ] self.order[3:] = order_remain self.im_ordered = np.transpose( self.im, self.order ) self.ax.set_aspect( self.asp * self.im_ordered.shape[0] / self.im_ordered.shape[1] * self.aspect ) self.update_image() elif ( self.order_valid ): self.order[:2] = self.order3[:2] order_remain = np.r_[:self.Ndims] for t in np.r_[:2]: order_remain = order_remain[ (order_remain != self.order[t] ) ] self.order[2:] = order_remain self.im_ordered = np.transpose( self.im, self.order ) self.ax.set_aspect( self.asp * self.im_ordered.shape[0] / self.im_ordered.shape[1] * self.aspect ) self.update_image() def update_image( self ): self.immax = np.max(abs(self.im)) self.l.set_clim( vmin = self.vmin * self.immax , vmax = self.vmax * self.immax ); if ( self.mosaic_valid ): im_slice = self.im_ordered[ (slice(None,None,self.flipx), slice(None,None,self.flipy), slice(None)) + tuple(self.slice_num[self.order[3:]])] im_slice = self.mosaic( im_slice ) else: im_slice = self.im_ordered[ (slice(None,None,self.flipx), slice(None,None,self.flipy)) + tuple(self.slice_num[self.order[2:]]) ] if self.magnitude: self.l.set_data( abs(im_slice) ) else: self.l.set_data( (np.angle(im_slice) + np.pi) / (2 * np.pi) ) self.fig.canvas.draw() def update_slice( self, d, s ): self.slice_num[d] = int(round(s)) self.update_image() def mosaic( self, im ): im = im.squeeze() (x, y, z) = im.shape z2 = int( np.ceil( z ** 0.5 ) ) z = int( z2 ** 2 ) im = np.pad( im, [(0,0), (0,0), (0, z - im.shape[2] )], mode='constant') im = im.reshape( (x, y * z, 1), order = 'F' ) im = im.transpose( (1, 2, 0) ) im = im.reshape( (y * z2 , z2, x), order = 'F' ) im = im.transpose( (2, 1, 0) ) im = im.reshape( (x * z2, y * z2), order = 'F' ) return im def update_mosaic( self, l ): l = int(l[4:]) self.order3[2] = np.where( self.im_unsqueeze_shape == l )[0] self.update_ordered_image() if __name__ == "__main__": # Error if more than 1 argument if (len(sys.argv) != 2): print("BartView: multidimensional image viewer for cfl") print("Usage: bview cflname") exit() BartView( sys.argv[1] ) bart-0.5.00/python/cfl.py000066400000000000000000000022031353046746100151710ustar00rootroot00000000000000# Copyright 2013-2015. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # # Authors: # 2013 Martin Uecker # 2015 Jonathan Tamir import numpy as np def readcfl(name): # get dims from .hdr h = open(name + ".hdr", "r") h.readline() # skip l = h.readline() h.close() dims = [int(i) for i in l.split( )] # remove singleton dimensions from the end n = np.prod(dims) dims_prod = np.cumprod(dims) dims = dims[:np.searchsorted(dims_prod, n)+1] # load data and reshape into dims d = open(name + ".cfl", "r") a = np.fromfile(d, dtype=np.complex64, count=n); d.close() return a.reshape(dims, order='F') # column-major def writecfl(name, array): h = open(name + ".hdr", "w") h.write('# Dimensions\n') for i in (array.shape): h.write("%d " % i) h.write('\n') h.close() d = open(name + ".cfl", "w") array.T.astype(np.complex64).tofile(d) # tranpose for column-major order d.close() bart-0.5.00/python/wslsupport.py000066400000000000000000000006401353046746100166720ustar00rootroot00000000000000import string import os def PathCorrection(inData): outData=inData for i in string.ascii_lowercase: #Replace drive letters with /mnt/ outData=outData.replace(i+':','/mnt/'+i) #if drive letter is supplied in lowercase outData=outData.replace(i.upper()+':','/mnt/'+i) #if drive letter is supplied as uppercase outData=outData.replace(os.path.sep, '/') #Change windows filesep to linux filesep return outData bart-0.5.00/rules/000077500000000000000000000000001353046746100136675ustar00rootroot00000000000000bart-0.5.00/rules/box.mk000066400000000000000000000002021353046746100150020ustar00rootroot00000000000000 boxsrcs := $(XTARGETS:%=src/%.c) boxobjs := $(boxsrcs:.c=.o) .INTERMEDIATE: $(boxobjs) lib/libbox.a: libbox.a($(boxobjs)) bart-0.5.00/rules/calib.mk000066400000000000000000000007061353046746100152750ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. calibsrcs := $(wildcard $(srcdir)/calib/*.c) calibobjs := $(calibsrcs:.c=.o) ifeq ($(CUDA),1) calibcudasrcs += $(wildcard $(srcdir)/calib/*.cu) calibobjs += $(calibcudasrcs:.cu=.o) endif .INTERMEDIATE: $(calibobjs) lib/libcalib.a: libcalib.a($(calibobjs)) bart-0.5.00/rules/dfwavelet.mk000066400000000000000000000007661353046746100162120ustar00rootroot00000000000000# Copyright 2015. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. dfwaveletsrcs := $(wildcard $(srcdir)/dfwavelet/*.c) dfwaveletobjs := $(dfwaveletsrcs:.c=.o) dfwaveletcudasrcs := $(wildcard $(srcdir)/dfwavelet/*.cu) ifeq ($(CUDA),1) dfwaveletobjs += $(dfwaveletcudasrcs:.cu=.o) endif .INTERMEDIATE: $(dfwaveletobjs) lib/libdfwavelet.a: libdfwavelet.a($(dfwaveletobjs)) bart-0.5.00/rules/grecon.mk000066400000000000000000000005371353046746100155020ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. greconsrcs := $(wildcard $(srcdir)/grecon/*.c) greconobjs := $(greconsrcs:.c=.o) .INTERMEDIATE: $(greconobjs) lib/libgrecon.a: libgrecon.a($(greconobjs)) bart-0.5.00/rules/ismrm.mk000066400000000000000000000005761353046746100153570ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. ismrmsrcs := $(wildcard $(srcdir)/ismrm/*.c) ismrmobjs := $(ismrmsrcs:.c=.o) .INTERMEDIATE: $(ismrmobjs) lib/libismrm.a: libismrm.a($(ismrmobjs)) lib/libismrm.a: CPPFLAGS += $(ISMRM_H) bart-0.5.00/rules/iter.mk000066400000000000000000000006721353046746100151700ustar00rootroot00000000000000# Copyright 2014. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. itersrcs := $(wildcard $(srcdir)/iter/*.c) itercudasrcs := $(wildcard $(srcdir)/iter/*.cu) iterobjs := $(itersrcs:.c=.o) ifeq ($(CUDA),1) iterobjs += $(itercudasrcs:.cu=.o) endif .INTERMEDIATE: $(iterobjs) lib/libiter.a: libiter.a($(iterobjs)) bart-0.5.00/rules/lapacke.mk000066400000000000000000000002471353046746100156230ustar00rootroot00000000000000 lapackesrcs := $(wildcard $(srcdir)/lapacke/*.c) lapackeobjs := $(lapackesrcs:.c=.o) .INTERMEDIATE: $(lapackeobjs) lib/liblapacke.a: liblapacke.a($(lapackeobjs)) bart-0.5.00/rules/linops.mk000066400000000000000000000010771353046746100155310ustar00rootroot00000000000000# Copyright 2014. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. linopssrcs := $(wildcard $(srcdir)/linops/*.c) linopscudasrcs := $(wildcard $(srcdir)/linops/*.cu) linopsobjs := $(linopssrcs:.c=.o) ifeq ($(CUDA),1) linopsobjs += $(linopscudasrcs:.cu=.o) endif .INTERMEDIATE: $(linopsobjs) lib/liblinops.a: liblinops.a($(linopsobjs)) UTARGETS += test_linop_matrix test_linop MODULES_test_linop += -llinops MODULES_test_linop_matrix += -llinops bart-0.5.00/rules/lowrank.mk000066400000000000000000000007261353046746100157020ustar00rootroot00000000000000# Copyright 2015. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. lowranksrcs := $(wildcard $(srcdir)/lowrank/*.c) #lowranksrcs := $(wildcard $(srcdir)/lowrank/lr*.c) lowrankobjs := $(lowranksrcs:.c=.o) .INTERMEDIATE: $(lowrankobjs) lib/liblowrank.a: liblowrank.a($(lowrankobjs)) UTARGETS += test_batchsvd MODULES_test_batchsvd = -llowrank bart-0.5.00/rules/make_symbol_table.sh000077500000000000000000000001311353046746100176720ustar00rootroot00000000000000#!/bin/bash EXEC=$1 OUT=$2 nm --defined-only ${EXEC} | cut -c11-16,19- | sort > ${OUT} bart-0.5.00/rules/misc.mk000066400000000000000000000010451353046746100151530ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # Copyright 2015. Martin Uecker. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. miscsrcs := $(wildcard $(srcdir)/misc/*.c) miscobjs := $(miscsrcs:.c=.o) miscobjs += $(miscextracxxsrcs:.cc=.o) .INTERMEDIATE: $(miscobjs) lib/libmisc.a: libmisc.a($(miscobjs)) DOTHIS := $(shell $(root)/rules/update-version.sh) $(srcdir)/misc/version.o: $(srcdir)/misc/version.inc UTARGETS += test_pattern test_types bart-0.5.00/rules/moba.mk000066400000000000000000000003251353046746100151360ustar00rootroot00000000000000 mobasrcs := $(wildcard $(srcdir)/moba/*.c) mobaobjs := $(mobasrcs:.c=.o) .INTERMEDIATE: $(mobaobjs) lib/libmoba.a: libmoba.a($(mobaobjs)) UTARGETS += test_moba MODULES_test_moba += -lmoba -lnlops -llinops bart-0.5.00/rules/nlops.mk000066400000000000000000000004071353046746100153540ustar00rootroot00000000000000 nlopssrcs := $(wildcard $(srcdir)/nlops/*.c) nlopscudasrcs := $(wildcard $(srcdir)/nlops/*.cu) nlopsobjs := $(nlopssrcs:.c=.o) .INTERMEDIATE: $(nlopsobjs) lib/libnlops.a: libnlops.a($(nlopsobjs)) UTARGETS += test_nlop MODULES_test_nlop += -lnlops -llinops bart-0.5.00/rules/noir.mk000066400000000000000000000005171353046746100151720ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. noirsrcs := $(wildcard $(srcdir)/noir/*.c) noirobjs := $(noirsrcs:.c=.o) .INTERMEDIATE: $(noirobjs) lib/libnoir.a: libnoir.a($(noirobjs)) bart-0.5.00/rules/noncart.mk000066400000000000000000000006461353046746100156720ustar00rootroot00000000000000# Copyright 2014. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. noncartsrcs := $(wildcard $(srcdir)/noncart/*.c) noncartobjs := $(noncartsrcs:.c=.o) .INTERMEDIATE: $(noncartobjs) lib/libnoncart.a: libnoncart.a($(noncartobjs)) UTARGETS += test_nufft MODULES_test_nufft += -lnoncart -llinops bart-0.5.00/rules/num.mk000066400000000000000000000010721353046746100150170ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. numsrcs := $(wildcard $(srcdir)/num/*.c) numcudasrcs := $(wildcard $(srcdir)/num/*.cu) numobjs := $(numsrcs:.c=.o) ifeq ($(CUDA),1) numobjs += $(numcudasrcs:.cu=.o) endif .INTERMEDIATE: $(numobjs) lib/libnum.a: libnum.a($(numobjs)) UTARGETS += test_multind test_flpmath test_splines test_linalg test_polynom test_window UTARGETS += test_blas test_mdfft test_ops test_ops_p bart-0.5.00/rules/sake.mk000066400000000000000000000005161353046746100151450ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. sakesrcs := $(wildcard $(srcdir)/sake/*.c) sakeobjs := $(sakesrcs:.c=.o) .INTERMEDIATE: $(sakeobjs) lib/libsake.a: libsake.a($(sakeobjs)) bart-0.5.00/rules/sense.mk000066400000000000000000000005271353046746100153410ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. sensesrcs := $(wildcard $(srcdir)/sense/*.c) senseobjs := $(sensesrcs:.c=.o) .INTERMEDIATE: $(senseobjs) lib/libsense.a: libsense.a($(senseobjs)) bart-0.5.00/rules/simu.mk000066400000000000000000000006771353046746100152070ustar00rootroot00000000000000# Copyright 2013. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. simusrcs := $(wildcard $(srcdir)/simu/*.c) simuobjs := $(simusrcs:.c=.o) .INTERMEDIATE: $(simuobjs) lib/libsimu.a: libsimu.a($(simuobjs)) UTARGETS += test_ode_bloch test_biot_savart MODULES_test_ode_bloch += -lsimu MODULES_test_biot_savart += -lsimu bart-0.5.00/rules/update-if-changed.sh000077500000000000000000000000561353046746100174740ustar00rootroot00000000000000#!/bin/bash cmp -s $1 $2 || mv $1 $2 rm -f $1 bart-0.5.00/rules/update-version.sh000077500000000000000000000002211353046746100171660ustar00rootroot00000000000000#!/bin/bash echo 'VERSION('`./git-version.sh`')' > version.new ./rules/update-if-changed.sh version.new src/misc/version.inc rm -f version.new bart-0.5.00/rules/update_commands.sh000077500000000000000000000005771353046746100174020ustar00rootroot00000000000000#!/bin/bash set -e BINDIR=$(dirname $0) BART_EXE=$1 shift OUTPUT=$1 shift XTARGETS=$@ TEST_FILE_COMMANDS=$(mktemp) echo "AUTOGENERATED. DO NOT EDIT." > ${TEST_FILE_COMMANDS} for cmd in ${XTARGETS} ; do printf "\n\n--%s--\n\n" $cmd ; ${BART_EXE} $cmd -h ; done >> ${TEST_FILE_COMMANDS} ${BINDIR}/update-if-changed.sh ${TEST_FILE_COMMANDS} ${OUTPUT} rm -rf ${TEST_FILE_COMMANDS} bart-0.5.00/rules/wavelet.mk000066400000000000000000000004361353046746100156720ustar00rootroot00000000000000 waveletsrcs := $(wildcard $(srcdir)/wavelet/*.c) waveletobjs := $(waveletsrcs:.c=.o) waveletcudasrcs := $(wildcard $(srcdir)/wavelet/*.cu) ifeq ($(CUDA),1) waveletobjs += $(waveletcudasrcs:.cu=.o) endif .INTERMEDIATE: $(waveletobjs) lib/libwavelet.a: libwavelet.a($(waveletobjs)) bart-0.5.00/save/000077500000000000000000000000001353046746100134735ustar00rootroot00000000000000bart-0.5.00/save/fftw/000077500000000000000000000000001353046746100144415ustar00rootroot00000000000000bart-0.5.00/save/fftw/README.txt000066400000000000000000000000221353046746100161310ustar00rootroot00000000000000Saves FFT wisdom. bart-0.5.00/save/nsv/000077500000000000000000000000001353046746100143015ustar00rootroot00000000000000bart-0.5.00/save/nsv/README.txt000066400000000000000000000000731353046746100157770ustar00rootroot00000000000000This folder is to save the simulations done by estvar/nsv. bart-0.5.00/scripts/000077500000000000000000000000001353046746100142245ustar00rootroot00000000000000bart-0.5.00/scripts/bart_completion.sh000066400000000000000000000014721353046746100177450ustar00rootroot00000000000000# bart parameter-completion function _bart() { local cur=${COMP_WORDS[$COMP_CWORD]} if [ $COMP_CWORD -eq 1 ] ; then local CMDS=$(bart | tail -n +2) COMPREPLY=($(compgen -W "$CMDS" -- "$cur")); else local bcmd=${COMP_WORDS[1]} case $cur in -*) COMPREPLY=($(bart ${bcmd} -h | grep -o -E "^${cur}\w*")) ;; *) case $bcmd in twixread) COMPREPLY=($(compgen -o plusdirs -f -X '!*.dat' -- ${cur})) ;; *) local CFLS=$(compgen -o plusdirs -f -X '!*.hdr' -- ${cur}) local COOS=$(compgen -o plusdirs -f -X '!*.coo' -- ${cur}); local RAS=$(compgen -o plusdirs -f -X '!*.ra' -- ${cur}); local suffix=".hdr" COMPREPLY=($(for i in ${CFLS} ${COOS} ${RAS}; do echo ${i%$suffix} ; done)) ;; esac ;; esac fi return 0 } complete -o filenames -F _bart bart ./bart bart-0.5.00/scripts/espirit_econ.sh000066400000000000000000000035761353046746100172560ustar00rootroot00000000000000#!/bin/bash # Copyright 2018. Martin Uecker. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # # Authors: # 2018 Martin Uecker # # Memory-saving ESPIRiT # set -e LOGFILE=/dev/stdout title=$(cat <<- EOF ESPIRiT-ECON EOF ) helpstr=$(cat <<- EOF -l logfile -h help EOF ) usage="Usage: $0 [-h] " echo "$title" echo while getopts "hl:" opt; do case $opt in h) echo "$usage" echo echo "$helpstr" exit 0 ;; l) LOGFILE=$(readlink -f "$OPTARG") ;; \?) echo "$usage" >&2 exit 1 ;; esac done shift $((OPTIND - 1)) if [ $# -lt 2 ] ; then echo "$usage" >&2 exit 1 fi export PATH=$TOOLBOX_PATH:$PATH input=$(readlink -f "$1") output=$(readlink -f "$2") if [ ! -e $input.cfl ] ; then echo "Input file does not exist." >&2 echo "$usage" >&2 exit 1 fi if [ ! -e $TOOLBOX_PATH/bart ] ; then echo "\$TOOLBOX_PATH is not set correctly!" >&2 exit 1 fi #WORKDIR=$(mktemp -d) # Mac: http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x WORKDIR=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` trap 'rm -rf "$WORKDIR"' EXIT cd $WORKDIR # start group for redirection of output to the logfile { XX=$(bart show -d0 $input) YY=$(bart show -d1 $input) ZZ=$(bart show -d2 $input) DIM=2 # To decouple along another dimension: # 1. change DIM # 2. replace ZZ below # 3. change the ecaltwo command bart ecalib -1 $input eon # zero-pad bart fft $(bart bitmask ${DIM}) eon eon_fft bart resize -c ${DIM} ${ZZ} eon_fft eon_fft2 bart fft -i $(bart bitmask ${DIM}) eon_fft2 eon for i in `seq -w 0 $(($ZZ - 1))` ; do bart slice ${DIM} $i eon sl bart ecaltwo ${XX} ${YY} 1 sl sens-$i.coo done # # join slices back together bart join ${DIM} sens-*.coo $output } > $LOGFILE exit 0 bart-0.5.00/scripts/grasp.sh000066400000000000000000000124761353046746100157060ustar00rootroot00000000000000#!/bin/bash # Copyright 2015. The Regents of the University of California. # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # # Authors: # 2015 Martin Uecker # # Compressed sensing parallel imaging reconstruction with temporal # total-variation regularization for Siemens radial VIBE sequence # with golden-angle sampling (GRASP). # set -e # default settings export SPOKES=21 export SKIP=0 export CALIB=400 export ITER=30 export REG=0.05 SCALE=0.6 LOGFILE=/dev/stdout MAXPROC=4 MAXTHREADS=4 title=$(cat <<- EOF (BART-)GRASP v0.3 (Berkeley Advanced Reconstruction Toolbox) --- EXPERIMENTAL --- FOR RESEARCH USE ONLY --- EOF ) helpstr=$(cat <<- EOF Compressed sensing parallel imaging reconstruction with temporal total-variation regularization for Siemens radial VIBE sequence with golden-angle sampling (GRASP). This script requires the Berkeley Advanced Reconstruction Toolbox version 0.2.09. (later versions may also work). -s spokes number of spokes per frame -r lambda regularization parameter -p maxproc max. number of slices processed in parallel -t maxthreads max. number of threads per slice -l logfile -h help EOF ) usage="Usage: $0 [-h] [-s spokes] [-r lambda] " echo "$title" echo while getopts "hl:s:p:t:r:" opt; do case $opt in s) SPOKES=$OPTARG ;; r) REG=$OPTARG ;; h) echo "$usage" echo echo "$helpstr" exit 0 ;; l) LOGFILE=$(readlink -f "$OPTARG") ;; p) MAXPROC=$OPTARG ;; t) MAXTHREADS=$OPTARG ;; \?) echo "$usage" >&2 exit 1 ;; esac done shift $((OPTIND - 1)) if [ $# -lt 2 ] ; then echo "$usage" >&2 exit 1 fi export PATH=$TOOLBOX_PATH:$PATH input=$(readlink -f "$1") output=$(readlink -f "$2") if [ ! -e $input ] ; then echo "Input file does not exist." >&2 echo "$usage" >&2 exit 1 fi if [ ! -e $TOOLBOX_PATH/bart ] ; then echo "\$TOOLBOX_PATH is not set correctly!" >&2 exit 1 fi #WORKDIR=$(mktemp -d) # Mac: http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x WORKDIR=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` trap 'rm -rf "$WORKDIR"' EXIT cd $WORKDIR # start group for redirection of output to the logfile { # read TWIX file bart twixread -A $input grasp export READ=$(bart show -d0 grasp) export COILS=$(bart show -d3 grasp) export PHASES=$(($(bart show -d1 grasp) / $SPOKES)) export OMP_NUM_THREADS=$((MAXPROC * $MAXTHREADS)) # zero-pad #flip $(bitmask 2) grasp grasp2 #resize 2 64 grasp2 grasp #circshift 2 10 grasp grasp2 #fft -u $(bitmask 2) grasp2 grasp_hybrid #rm grasp.* grasp2.* # inverse FFT along 3rd dimension bart fft -i -u $(bart bitmask 2) grasp grasp_hybrid rm grasp.cfl grasp.hdr SLICES=$(bart show -d2 grasp_hybrid) # create trajectory with 400 spokes and 2x oversampling bart traj -G -x$READ -y$CALIB r bart scale $SCALE r rcalib # create trajectory with 2064 spokes and 2x oversampling bart traj -G -x$READ -y$(($SPOKES * $PHASES)) r bart scale $SCALE r r2 # split off time dimension into index 10 bart reshape $(bart bitmask 2 10) $SPOKES $PHASES r2 rfull # number of threads per slice export OMP_NUM_THREADS=$MAXTHREADS calib_slice() { # extract slice bart slice 2 $1 grasp_hybrid grasp1-$1 # extract first $CALIB spokes bart extract 1 $(($SKIP + 0)) $(($SKIP + $CALIB)) grasp1-$1 grasp2-$1 # reshape dimensions bart reshape $(bart bitmask 0 1 2 3) 1 $READ $CALIB $COILS grasp2-$1 grasp3-$1 # apply inverse nufft to first $CALIB spokes bart nufft -i -t rcalib grasp3-$1 img-$1.coo } recon_slice() { # extract sensitivities for slice bart slice 2 $1 sens sens-$1 # extract spokes and split-off time dim bart extract 1 $(($SKIP + 0)) $(($SKIP + $SPOKES * $PHASES)) grasp1-$1 grasp2-$1 bart reshape $(bart bitmask 1 2) $SPOKES $PHASES grasp2-$1 grasp1-$1 # move time dimensions to dim 10 and reshape bart transpose 2 10 grasp1-$1 grasp2-$1 bart reshape $(bart bitmask 0 1 2) 1 $READ $SPOKES grasp2-$1 grasp1-$1 rm grasp2-$1.cfl grasp2-$1.hdr # reconstruction with tv penality along dimension 10 # old (v0.2.08): # pics -S -d5 -lv -u10. -r$REG -R$(bitmask 10) -i$ITER -t rfull grasp1-$1 sens-$1 i-$1.coo # new (v0.2.09): bart pics -S -d5 -u10. -RT:$(bart bitmask 10):0:$REG -i$ITER -t rfull grasp1-$1 sens-$1 i-$1.coo # clean up temp files rm *-$1.cfl *-$1.hdr } export -f calib_slice export -f recon_slice # loop over slices seq -w 0 $(($SLICES - 1)) | xargs -I {} -P $MAXPROC bash -c "calib_slice {}" # transform back to k-space and compute sensitivities bart join 2 img-*.coo img bart fft -u $(bart bitmask 0 1 2) img ksp #ecalib -S -c0.8 -m1 -r20 ksp sens # transpose because we already support off-center calibration region # in dim 0 but here we might have it in 2 bart transpose 0 2 ksp ksp2 bart ecalib -S -c0.8 -m1 -r20 ksp2 sens2 bart transpose 0 2 sens2 sens # loop over slices seq -w 0 $(($SLICES - 1)) | xargs -I {} -P $MAXPROC bash -c "recon_slice {}" #echo 20 | xargs -i --max-procs=$MAXPROC bash -c "recon_slice {}" # join slices back together bart join 2 i-*.coo $output # generate dicoms #for s in $(seq -w 0 $(($SLICES - 1))) ; do # for p in $(seq -w 0 $(($PHASES - 1))) ; do # bart slice 10 $p i-$s.coo i-$p-$s.coo # bart toimg i-$p-$s.coo $output.series$p.slice$s.dcm # done #done } > $LOGFILE exit 0 bart-0.5.00/scripts/octview.m000077500000000000000000000002501353046746100160620ustar00rootroot00000000000000#! /usr/bin/octave -qf addpath(strcat(getenv("TOOLBOX_PATH"), "/matlab")); arg_list = argv(); data = squeeze(readcfl(arg_list{1})); imshow3(abs(data), []); pause; bart-0.5.00/scripts/profile.sh000066400000000000000000000022511353046746100162200ustar00rootroot00000000000000#!/bin/sh set -e usage="Usage: $0 " helpstr=$(cat <<- EOF Postprocess debugging output from BART to extract profiling information and to translate pointer values to symbol names. -h help EOF ) while getopts "h" opt; do case $opt in h) echo "$usage" echo echo "$helpstr" exit 0 ;; \?) echo "$usage" >&2 exit 1 ;; esac done shift $((OPTIND - 1)) if [ $# -lt 2 ] ; then echo "$usage" >&2 exit 1 fi in=$(readlink -f "$1") out=$(readlink -f "$2") if [ ! -e $input ] ; then echo "Input file does not exist." >&2 echo "$usage" >&2 exit 1 fi if [ ! -e $TOOLBOX_PATH/bart ] ; then echo "\$TOOLBOX_PATH is not set correctly!" >&2 exit 1 fi #WORKDIR=$(mktemp -d) # Mac: http://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x WORKDIR=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'` trap 'rm -rf "$WORKDIR"' EXIT cd $WORKDIR nm --defined-only $TOOLBOX_PATH/bart | cut -c11-16,19- | sort > bart.syms cat $in | grep "^TRACE" \ | grep " 0x" \ | cut -c7-23,25-31,34- \ | sort -k3 \ | join -11 -23 bart.syms - \ | cut -c8- \ | sort -k2 > $out bart-0.5.00/scripts/rtnlinv.m000066400000000000000000000026441353046746100161040ustar00rootroot00000000000000% 2015, Martin Uecker % % Example script to use BART for the initial preprocessing % (gridding) which is required - but not included - in the % original Matlab RT-NLINV example. The example is for a % single frame, but this should also work in a similar way % for the RT-NLINV2 code which reconstructs a time-series % of images from highly undersampled data using temporal % regularization. % % Links to the Matlab code can be found here: % http://www.eecs.berkeley.edu/~uecker/toolbox.html % % References: % % Uecker M et al., Nonlinear Inverse Reconstruction for Real-time MRI % of the Human Heart Using Undersampled Radial FLASH, % MRM 63:1456-1462 (2010) % % Uecker M et al., Real-time magnetic resonance imaging at 20 ms % resolution, NMR in Biomedicine 23: 986-994 (2010) % % data set is included in the IRGNTV example A = load('radial_cardiac_25_projections.mat'); % re-format trajectory for BART t = zeros(3, 256, 25); t(1,:,:) = real(A.k) * 384.; t(2,:,:) = imag(A.k) * 384.; % use adjoint nufft to interpolate data onto Cartesia grid adj = bart('nufft -d384:384:1 -a ', t, reshape(A.rawdata, [1 256 25 12])); % compute point-spread function psf = bart('nufft -d384:384:1 -a ', t, ones(1, 256, 25)); % transform back to k-space adjk = bart('fft -u 7', adj); psfk = bart('fft -u 7', psf); % use nlinv from RT-NLINV (nlinv2) matlab package R = nlinv(squeeze(adjk), squeeze(psfk) * 1., 9, 'noncart'); bart-0.5.00/src/000077500000000000000000000000001353046746100133245ustar00rootroot00000000000000bart-0.5.00/src/avg.c000066400000000000000000000023551353046746100142520ustar00rootroot00000000000000/* Copyright 2014-2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Calculates (weighted) average along dimensions specified by bitmask."; int main_avg(int argc, char* argv[argc]) { bool wavg = false; const struct opt_s opts[] = { OPT_SET('w', &wavg, "weighted average"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); int N = DIMS; unsigned int flags = atoi(argv[1]); long idims[N]; complex float* data = load_cfl(argv[2], N, idims); long odims[N]; md_select_dims(N, ~flags, odims, idims); complex float* out = create_cfl(argv[3], N, odims); (wavg ? md_zwavg : md_zavg)(N, idims, flags, out, data); unmap_cfl(N, idims, data); unmap_cfl(N, odims, out); return 0; } bart-0.5.00/src/bart.c000066400000000000000000000055531353046746100144300ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. + Copyright 2018. Damien Nguyen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2016 Martin Uecker */ #include #include #include #include #include #include #include #include "misc/io.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/cppmap.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #ifdef USE_LOCAL_FFTW #include "fftw3_local.h" #define MANGLE(name) local_ ## name #else #include #define MANGLE(name) name #endif #include "main.h" extern FILE* bart_output; // src/misc.c static void bart_exit_cleanup(void) { if (NULL != command_line) XFREE(command_line); io_memory_cleanup(); #ifdef FFTWTHREADS MANGLE(fftwf_cleanup_threads)(); #endif #ifdef USE_CUDA cuda_memcache_clear(); #endif } struct { int (*main_fun)(int argc, char* argv[]); const char* name; } dispatch_table[] = { #define DENTRY(x) { main_ ## x, # x }, MAP(DENTRY, MAIN_LIST) #undef DENTRY { NULL, NULL } }; static void usage(void) { printf("BART. Available commands are:"); for (int i = 0; NULL != dispatch_table[i].name; i++) { if (0 == i % 6) printf("\n"); printf("%-12s", dispatch_table[i].name); } printf("\n"); } int main_bart(int argc, char* argv[]) { char* bn = basename(argv[0]); if (0 == strcmp(bn, "bart")) { if (1 == argc) { usage(); return 1; } const char* tpath[] = { #ifdef TOOLBOX_PATH_OVERRIDE getenv("TOOLBOX_PATH"), #endif "/usr/local/lib/bart/commands/", "/usr/lib/bart/commands/", }; for (unsigned int i = 0; i < ARRAY_SIZE(tpath); i++) { if (NULL == tpath[i]) continue; size_t len = strlen(tpath[i]) + strlen(argv[1]) + 2; char cmd[len]; size_t r = snprintf(cmd, len, "%s/%s", tpath[i], argv[1]); assert(r < len); if (-1 == execv(cmd, argv + 1)) { // only if it doesn't exist - try builtin if (ENOENT != errno) { perror("Executing bart command failed"); return 1; } } else { assert(0); } } return main_bart(argc - 1, argv + 1); } for (int i = 0; NULL != dispatch_table[i].name; i++) if (0 == strcmp(bn, dispatch_table[i].name)) return dispatch_table[i].main_fun(argc, argv); fprintf(stderr, "Unknown bart command: \"%s\".\n", bn); return -1; } int bart_command(int len, char* buf, int argc, char* argv[]) { int save = debug_level; if (NULL != buf) { buf[0] = '\0'; bart_output = fmemopen(buf, len, "w"); } int ret = error_catcher(main_bart, argc, argv); bart_exit_cleanup(); debug_level = save; if (NULL != bart_output) { fclose(bart_output); // write final nul bart_output = NULL; } return ret; } bart-0.5.00/src/bart_embed_api.h000066400000000000000000000117041353046746100164150ustar00rootroot00000000000000#ifndef BART_API_H_INCLUDED #define BART_API_H_INCLUDED #ifdef __cplusplus extern "C" { #endif //! BART's current debug level extern int debug_level; //! Load the content of some in-memory CFL /*! * This function will load the data from some named in-memory CFL and returns * its data. * The dimensions array will get modified to match those from the CFL * * \param name Name used to refer to in-memory CFL * \param D Size of the dimensions array (should be < 16) * \param dimensions Array holding the dimensions of the data * (will get modified) * * \return Pointer to the data or NULL if no matching in-memory CFL file * was found */ void* load_mem_cfl(const char* name, unsigned int D, long dimensions[]); //! Register some memory into the list of in-memory CFL files /*! * This function handles data that was allocated using the C malloc(...) function. * It takes *ownership* of the data and will free it using free(...) * * \param name Name which will be used to refer to the created in-mem CFL * \param D Size of the dimensions array (should be < 16) * \param dimensions Array holding the dimensions of the data * \param ptr Pointer to the data * * \note The underlying data type of ptr is assumed to be complex floats * (complex float or _Complex float) * * \warning Calling this function on data allocated with new[] will result * in undefined behaviour! * * \warning Be aware that if MEMONLY_CFL is not defined, names that do not * end with the '.mem' extension will be unreachable by user code */ void register_mem_cfl_malloc(const char* name, unsigned int D, const long dimensions[], void* ptr); //! Register some memory into the list of in-memory CFL files /*! * This function handles data that was allocated using the C++ new[] operator * It takes *ownership* of the data and will free it using delete[] * * \param name Name which will be used to refer to the created in-mem CFL * \param D Size of the dimensions array (should be < 16) * \param dimensions Array holding the dimensions of the data * \param ptr Pointer to the data * * \note The underlying data type of ptr is assumed to be complex floats * (complex float or _Complex float) * * \warning Calling this function on data allocated with malloc will * result in undefined behaviour! * * \warning Be aware that if MEMONLY_CFL is not defined, names that do not * end with the '.mem' extension will be unreachable by user code */ void register_mem_cfl_new(const char* name, unsigned int D, const long dimensions[], void* ptr); //! Register some memory into the list of in-memory CFL files /*! * This function handles data that was allocated by the user and of which * the user wishes to retain control of its lifetime. * It does *not* takes ownership of the data * * \param name Name which will be used to refer to the created in-mem CFL * \param D Size of the dimensions array (should be < 16) * \param dimensions Array holding the dimensions of the data * \param ptr Pointer to the data * * \note The underlying data type of ptr is assumed to be complex floats * (complex float or _Complex float) * * \warning Be aware that if MEMONLY_CFL is not defined, names that do not * end with the '.mem' extension will be unreachable by user code */ void register_mem_cfl_non_managed(const char* name, unsigned int D, const long dims[], void* ptr); //! BART's main function /*! * This function will execute the BART command specified in argv[0] * * If applicable, the output of the BART command will be returned into * out. This applies to: * - bitmask * - estdims * - estvar * - nrmse * - sdot * - show * - version * * If out is not NULL, outputs of the above commands are redirected to out * * \param len Size of the out buffer * \param out Should be either NULL or point to a valid array of characters * \param argc Same as for the main function * \param argv Same as for the main function * * \warning Be aware that if MEMONLY_CFL is not defined, names that do not * end with the '.mem' extension will be unreachable by user code */ int bart_command(int len, char* out, int argc, char* argv[]); //! Deallocate any memory CFLs /*! * \note It is safe to call this function multiple times. */ void deallocate_all_mem_cfl(); #ifdef __cplusplus } #endif #endif //BART_API_H_INCLUDED bart-0.5.00/src/bbox.c000066400000000000000000000000601353046746100144160ustar00rootroot00000000000000 #define main_bart main_bbox #include "bart.c" bart-0.5.00/src/bench.c000066400000000000000000000337321353046746100145570ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2018 Martin Uecker * 2014 Jonathan Tamir */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "num/init.h" #include "num/ops_p.h" #include "num/mdfft.h" #include "num/fft.h" #include "wavelet/wavthresh.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/opts.h" #define DIMS 8 static double bench_generic_copy(long dims[DIMS]) { long strs[DIMS]; md_calc_strides(DIMS, strs, dims, CFL_SIZE); md_calc_strides(DIMS, strs, dims, CFL_SIZE); complex float* x = md_alloc(DIMS, dims, CFL_SIZE); complex float* y = md_alloc(DIMS, dims, CFL_SIZE); md_gaussian_rand(DIMS, dims, x); double tic = timestamp(); md_copy2(DIMS, dims, strs, y, strs, x, CFL_SIZE); double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_generic_matrix_multiply(long dims[DIMS]) { long dimsX[DIMS]; long dimsY[DIMS]; long dimsZ[DIMS]; #if 1 md_select_dims(DIMS, 2 * 3 + 17, dimsX, dims); // 1 110 1 md_select_dims(DIMS, 2 * 6 + 17, dimsY, dims); // 1 011 1 md_select_dims(DIMS, 2 * 5 + 17, dimsZ, dims); // 1 101 1 #else md_select_dims(DIMS, 2 * 5 + 17, dimsZ, dims); // 1 101 1 md_select_dims(DIMS, 2 * 3 + 17, dimsY, dims); // 1 110 1 md_select_dims(DIMS, 2 * 6 + 17, dimsX, dims); // 1 011 1 #endif complex float* x = md_alloc(DIMS, dimsX, CFL_SIZE); complex float* y = md_alloc(DIMS, dimsY, CFL_SIZE); complex float* z = md_alloc(DIMS, dimsZ, CFL_SIZE); md_gaussian_rand(DIMS, dimsX, x); md_gaussian_rand(DIMS, dimsY, y); double tic = timestamp(); md_ztenmul(DIMS, dimsZ, z, dimsX, x, dimsY, y); double toc = timestamp(); md_free(x); md_free(y); md_free(z); return toc - tic; } static double bench_generic_add(long dims[DIMS], unsigned int flags, bool forloop) { long dimsX[DIMS]; long dimsY[DIMS]; long dimsC[DIMS]; md_select_dims(DIMS, flags, dimsX, dims); md_select_dims(DIMS, ~flags, dimsC, dims); md_select_dims(DIMS, ~0u, dimsY, dims); long strsX[DIMS]; long strsY[DIMS]; md_calc_strides(DIMS, strsX, dimsX, CFL_SIZE); md_calc_strides(DIMS, strsY, dimsY, CFL_SIZE); complex float* x = md_alloc(DIMS, dimsX, CFL_SIZE); complex float* y = md_alloc(DIMS, dimsY, CFL_SIZE); md_gaussian_rand(DIMS, dimsX, x); md_gaussian_rand(DIMS, dimsY, y); long L = md_calc_size(DIMS, dimsC); long T = md_calc_size(DIMS, dimsX); double tic = timestamp(); if (forloop) { for (long i = 0; i < L; i++) { for (long j = 0; j < T; j++) y[i + j * L] += x[j]; } } else { md_zaxpy2(DIMS, dims, strsY, y, 1., strsX, x); } double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_generic_sum(long dims[DIMS], unsigned int flags, bool forloop) { long dimsX[DIMS]; long dimsY[DIMS]; long dimsC[DIMS]; md_select_dims(DIMS, ~0u, dimsX, dims); md_select_dims(DIMS, flags, dimsY, dims); md_select_dims(DIMS, ~flags, dimsC, dims); long strsX[DIMS]; long strsY[DIMS]; md_calc_strides(DIMS, strsX, dimsX, CFL_SIZE); md_calc_strides(DIMS, strsY, dimsY, CFL_SIZE); complex float* x = md_alloc(DIMS, dimsX, CFL_SIZE); complex float* y = md_alloc(DIMS, dimsY, CFL_SIZE); md_gaussian_rand(DIMS, dimsX, x); md_clear(DIMS, dimsY, y, CFL_SIZE); long L = md_calc_size(DIMS, dimsC); long T = md_calc_size(DIMS, dimsY); double tic = timestamp(); if (forloop) { for (long i = 0; i < L; i++) { for (long j = 0; j < T; j++) y[j] = y[j] + x[i + j * L]; } } else { md_zaxpy2(DIMS, dims, strsY, y, 1., strsX, x); } double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_copy1(long scale) { long dims[DIMS] = { 1, 128 * scale, 128 * scale, 1, 1, 16, 1, 16 }; return bench_generic_copy(dims); } static double bench_copy2(long scale) { long dims[DIMS] = { 262144 * scale, 16, 1, 1, 1, 1, 1, 1 }; return bench_generic_copy(dims); } static double bench_matrix_mult(long scale) { long dims[DIMS] = { 1, 256 * scale, 256 * scale, 256 * scale, 1, 1, 1, 1 }; return bench_generic_matrix_multiply(dims); } static double bench_batch_matmul1(long scale) { long dims[DIMS] = { 30000 * scale, 8, 8, 8, 1, 1, 1, 1 }; return bench_generic_matrix_multiply(dims); } static double bench_batch_matmul2(long scale) { long dims[DIMS] = { 1, 8, 8, 8, 30000 * scale, 1, 1, 1 }; return bench_generic_matrix_multiply(dims); } static double bench_tall_matmul1(long scale) { long dims[DIMS] = { 1, 8, 8, 100000 * scale, 1, 1, 1, 1 }; return bench_generic_matrix_multiply(dims); } static double bench_tall_matmul2(long scale) { long dims[DIMS] = { 1, 100000 * scale, 8, 8, 1, 1, 1, 1 }; return bench_generic_matrix_multiply(dims); } static double bench_add(long scale) { long dims[DIMS] = { 65536 * scale, 1, 50 * scale, 1, 1, 1, 1, 1 }; return bench_generic_add(dims, MD_BIT(2), false); } static double bench_addf(long scale) { long dims[DIMS] = { 65536 * scale, 1, 50 * scale, 1, 1, 1, 1, 1 }; return bench_generic_add(dims, MD_BIT(2), true); } static double bench_add2(long scale) { long dims[DIMS] = { 50 * scale, 1, 65536 * scale, 1, 1, 1, 1, 1 }; return bench_generic_add(dims, MD_BIT(0), false); } static double bench_sum2(long scale) { long dims[DIMS] = { 50 * scale, 1, 65536 * scale, 1, 1, 1, 1, 1 }; return bench_generic_sum(dims, MD_BIT(0), false); } static double bench_sum(long scale) { long dims[DIMS] = { 65536 * scale, 1, 50 * scale, 1, 1, 1, 1, 1 }; return bench_generic_sum(dims, MD_BIT(2), false); } static double bench_sumf(long scale) { long dims[DIMS] = { 65536 * scale, 1, 50 * scale, 1, 1, 1, 1, 1 }; return bench_generic_sum(dims, MD_BIT(2), true); } static double bench_zmul(long scale) { long dimsx[DIMS] = { 256, 256, 1, 1, 90 * scale, 1, 1, 1 }; long dimsy[DIMS] = { 256, 256, 1, 1, 1, 1, 1, 1 }; long dimsz[DIMS] = { 1, 1, 1, 1, 90 * scale, 1, 1, 1 }; complex float* x = md_alloc(DIMS, dimsx, CFL_SIZE); complex float* y = md_alloc(DIMS, dimsy, CFL_SIZE); complex float* z = md_alloc(DIMS, dimsz, CFL_SIZE); md_gaussian_rand(DIMS, dimsy, y); md_gaussian_rand(DIMS, dimsz, z); long strsx[DIMS]; long strsy[DIMS]; long strsz[DIMS]; md_calc_strides(DIMS, strsx, dimsx, CFL_SIZE); md_calc_strides(DIMS, strsy, dimsy, CFL_SIZE); md_calc_strides(DIMS, strsz, dimsz, CFL_SIZE); double tic = timestamp(); md_zmul2(DIMS, dimsx, strsx, x, strsy, y, strsz, z); double toc = timestamp(); md_free(x); md_free(y); md_free(z); return toc - tic; } static double bench_transpose(long scale) { long dims[DIMS] = { 2000 * scale, 2000 * scale, 1, 1, 1, 1, 1, 1 }; complex float* x = md_alloc(DIMS, dims, CFL_SIZE); complex float* y = md_alloc(DIMS, dims, CFL_SIZE); md_gaussian_rand(DIMS, dims, x); md_clear(DIMS, dims, y, CFL_SIZE); double tic = timestamp(); md_transpose(DIMS, 0, 1, dims, y, dims, x, CFL_SIZE); double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_resize(long scale) { long dimsX[DIMS] = { 2000 * scale, 1000 * scale, 1, 1, 1, 1, 1, 1 }; long dimsY[DIMS] = { 1000 * scale, 2000 * scale, 1, 1, 1, 1, 1, 1 }; complex float* x = md_alloc(DIMS, dimsX, CFL_SIZE); complex float* y = md_alloc(DIMS, dimsY, CFL_SIZE); md_gaussian_rand(DIMS, dimsX, x); md_clear(DIMS, dimsY, y, CFL_SIZE); double tic = timestamp(); md_resize(DIMS, dimsY, y, dimsX, x, CFL_SIZE); double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_norm(int s, long scale) { long dims[DIMS] = { 256 * scale, 256 * scale, 1, 16, 1, 1, 1, 1 }; #if 0 complex float* x = md_alloc_gpu(DIMS, dims, CFL_SIZE); complex float* y = md_alloc_gpu(DIMS, dims, CFL_SIZE); #else complex float* x = md_alloc(DIMS, dims, CFL_SIZE); complex float* y = md_alloc(DIMS, dims, CFL_SIZE); #endif md_gaussian_rand(DIMS, dims, x); md_gaussian_rand(DIMS, dims, y); double tic = timestamp(); switch (s) { case 0: md_zscalar(DIMS, dims, x, y); break; case 1: md_zscalar_real(DIMS, dims, x, y); break; case 2: md_znorm(DIMS, dims, x); break; case 3: md_z1norm(DIMS, dims, x); break; } double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_zscalar(long scale) { return bench_norm(0, scale); } static double bench_zscalar_real(long scale) { return bench_norm(1, scale); } static double bench_znorm(long scale) { return bench_norm(2, scale); } static double bench_zl1norm(long scale) { return bench_norm(3, scale); } static double bench_wavelet(long scale) { long dims[DIMS] = { 1, 256 * scale, 256 * scale, 1, 16, 1, 1, 1 }; long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(dims[0], 16); minsize[1] = MIN(dims[1], 16); minsize[2] = MIN(dims[2], 16); const struct operator_p_s* p = prox_wavelet_thresh_create(DIMS, dims, 6, 0u, minsize, 1.1, true); complex float* x = md_alloc(DIMS, dims, CFL_SIZE); md_gaussian_rand(DIMS, dims, x); double tic = timestamp(); operator_p_apply(p, 0.98, DIMS, dims, x, DIMS, dims, x); double toc = timestamp(); md_free(x); operator_p_free(p); return toc - tic; } static double bench_generic_mdfft(long dims[DIMS], unsigned long flags) { complex float* x = md_alloc(DIMS, dims, CFL_SIZE); complex float* y = md_alloc(DIMS, dims, CFL_SIZE); md_gaussian_rand(DIMS, dims, x); double tic = timestamp(); md_fft(DIMS, dims, flags, 0u, y, x); double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_mdfft(long scale) { long dims[DIMS] = { 1, 128 * scale, 128 * scale, 1, 1, 4, 1, 4 }; return bench_generic_mdfft(dims, 6ul); } static double bench_generic_fft(long dims[DIMS], unsigned long flags) { complex float* x = md_alloc(DIMS, dims, CFL_SIZE); complex float* y = md_alloc(DIMS, dims, CFL_SIZE); md_gaussian_rand(DIMS, dims, x); double tic = timestamp(); fft(DIMS, dims, flags, y, x); double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_fft(long scale) { long dims[DIMS] = { 1, 256 * scale, 256 * scale, 1, 1, 16, 1, 8 }; return bench_generic_fft(dims, 6ul); } static double bench_generic_fftmod(long dims[DIMS], unsigned long flags) { complex float* x = md_alloc(DIMS, dims, CFL_SIZE); complex float* y = md_alloc(DIMS, dims, CFL_SIZE); md_gaussian_rand(DIMS, dims, x); double tic = timestamp(); fftmod(DIMS, dims, flags, y, x); double toc = timestamp(); md_free(x); md_free(y); return toc - tic; } static double bench_fftmod(long scale) { long dims[DIMS] = { 1, 256 * scale, 256 * scale, 1, 1, 16, 1, 16 }; return bench_generic_fftmod(dims, 6ul); } enum bench_indices { REPETITION_IND, SCALE_IND, THREADS_IND, TESTS_IND, BENCH_DIMS }; typedef double (*bench_fun)(long scale); static void do_test(const long dims[BENCH_DIMS], complex float* out, long scale, bench_fun fun, const char* str) { printf("%30.30s |", str); int N = dims[REPETITION_IND]; double sum = 0.; double min = 1.E10; double max = 0.; for (int i = 0; i < N; i++) { double dt = fun(scale); sum += dt; min = MIN(dt, min); max = MAX(dt, max); printf(" %3.4f", (float)dt); fflush(stdout); assert(0 == REPETITION_IND); out[i] = dt; } printf(" | Avg: %3.4f Max: %3.4f Min: %3.4f\n", (float)(sum / N), max, min); } const struct benchmark_s { bench_fun fun; const char* str; } benchmarks[] = { { bench_add, "add (md_zaxpy)" }, { bench_add2, "add (md_zaxpy), contiguous" }, { bench_addf, "add (for loop)" }, { bench_sum, "sum (md_zaxpy)" }, { bench_sum2, "sum (md_zaxpy), contiguous" }, { bench_sumf, "sum (for loop)" }, { bench_zmul, "complex mult. (md_zmul2)" }, { bench_transpose, "complex transpose" }, { bench_resize, "complex resize" }, { bench_matrix_mult, "complex matrix multiply" }, { bench_batch_matmul1, "batch matrix multiply 1" }, { bench_batch_matmul2, "batch matrix multiply 2" }, { bench_tall_matmul1, "tall matrix multiply 1" }, { bench_tall_matmul2, "tall matrix multiply 2" }, { bench_zscalar, "complex dot product" }, { bench_zscalar, "complex dot product" }, { bench_zscalar_real, "real complex dot product" }, { bench_znorm, "l2 norm" }, { bench_zl1norm, "l1 norm" }, { bench_copy1, "copy 1" }, { bench_copy2, "copy 2" }, { bench_wavelet, "wavelet soft thresh" }, { bench_mdfft, "(MD-)FFT" }, { bench_fft, "FFT" }, { bench_fftmod, "fftmod" }, }; static const char usage_str[] = "[]"; static const char help_str[] = "Performs a series of micro-benchmarks."; int main_bench(int argc, char* argv[]) { bool threads = false; bool scaling = false; long flags = ~0l; const struct opt_s opts[] = { OPT_SET('T', &threads, "varying number of threads"), OPT_SET('S', &scaling, "varying problem size"), OPT_LONG('s', &flags, "flags", "select benchmarks"), }; cmdline(&argc, argv, 0, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); long dims[BENCH_DIMS] = MD_INIT_ARRAY(BENCH_DIMS, 1); long strs[BENCH_DIMS]; long pos[BENCH_DIMS] = { 0 }; dims[REPETITION_IND] = 5; dims[THREADS_IND] = threads ? 8 : 1; dims[SCALE_IND] = scaling ? 5 : 1; dims[TESTS_IND] = sizeof(benchmarks) / sizeof(benchmarks[0]); md_calc_strides(BENCH_DIMS, strs, dims, CFL_SIZE); bool outp = (2 == argc); complex float* out = (outp ? create_cfl : anon_cfl)(outp ? argv[1] : "", BENCH_DIMS, dims); num_init(); md_clear(BENCH_DIMS, dims, out, CFL_SIZE); do { if (!(flags & (1 << pos[TESTS_IND]))) continue; if (threads) { num_set_num_threads(pos[THREADS_IND] + 1); debug_printf(DP_INFO, "%02d threads. ", pos[THREADS_IND] + 1); } do_test(dims, &MD_ACCESS(BENCH_DIMS, strs, pos, out), pos[SCALE_IND] + 1, benchmarks[pos[TESTS_IND]].fun, benchmarks[pos[TESTS_IND]].str); } while (md_next(BENCH_DIMS, dims, ~MD_BIT(REPETITION_IND), pos)); unmap_cfl(BENCH_DIMS, dims, out); return 0; } bart-0.5.00/src/bitmask.c000066400000000000000000000023561353046746100151300ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2016 Martin Uecker */ #include #include #include "num/multind.h" #include "misc/misc.h" #include "misc/opts.h" static const char usage_str[] = "-b | ... "; static const char help_str[] = "Convert between a bitmask and set of dimensions."; int main_bitmask(int argc, char* argv[]) { bool inverse = false; long flags = 0; const struct opt_s opts[] = { OPT_SET('b', &inverse, "dimensions from bitmask"), }; cmdline(&argc, argv, 0, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); if ((2 != argc) && inverse) error("exactly one argument needed.\n"); if (!inverse) { for (int i = 1; i < argc; i++) { int d = atoi(argv[i]); assert(d >= 0); flags = MD_SET(flags, d); } bart_printf("%ld\n", flags); } else { int i = 0; flags = atoi(argv[1]); while (flags) { if (flags & 1) bart_printf("%d ", i); flags >>= 1; i++; } bart_printf("\n"); } return 0; } bart-0.5.00/src/cabs.c000066400000000000000000000016761353046746100144120ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Siddharth Iyer */ #include #include #include #include #include "num/init.h" #include "num/flpmath.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Absolute value of array (||).\n"; int main_cabs(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long dims[DIMS]; complex float* idata = load_cfl(argv[1], DIMS, dims); complex float* odata = create_cfl(argv[2], DIMS, dims); md_zabs(DIMS, dims, odata, idata); unmap_cfl(DIMS, dims, idata); unmap_cfl(DIMS, dims, odata); return 0; } bart-0.5.00/src/caldir.c000066400000000000000000000031411353046746100147250ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker * uecker@eecs.berkeley.edu */ #include #include #include #include #include #include "misc/mmio.h" #include "misc/misc.h" #include "misc/mri.h" #include "num/multind.h" #include "num/fft.h" #include "calib/direct.h" static const char usage_str[] = "cal_size "; static const char help_str[] = "Estimates coil sensitivities from the k-space center using\n" "a direct method (McKenzie et al.). The size of the fully-sampled\n" "calibration region is automatically determined but limited by\n" "{cal_size} (e.g. in the readout direction).\n"; int main_caldir(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); long dims[DIMS]; complex float* in_data = load_cfl(argv[2], DIMS, dims); int calsize_ro = atoi(argv[1]); long calsize[3] = { calsize_ro, calsize_ro, calsize_ro }; assert((dims[0] == 1) || (calsize_ro < dims[0])); assert(1 == dims[4]); complex float* out_data = create_cfl(argv[3], DIMS, dims); long caldims[DIMS]; complex float* cal_data = extract_calib(caldims, calsize, dims, in_data, false); printf("Calibration region %ldx%ldx%ld\n", caldims[0], caldims[1], caldims[2]); direct_calib(dims, out_data, caldims, cal_data); printf("Done.\n"); md_free(cal_data); unmap_cfl(DIMS, dims, (void*)out_data); unmap_cfl(DIMS, dims, (void*)in_data); return 0; } bart-0.5.00/src/calib/000077500000000000000000000000001353046746100143765ustar00rootroot00000000000000bart-0.5.00/src/calib/calib.c000066400000000000000000000524151353046746100156230ustar00rootroot00000000000000/* Copyright 2013-2016. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * 2013 Dara Bahri * 2015-2016 Siddharth Iyer * * * Uecker M, Lai P, Murphy MJ, Virtue P, Elad M, Pauly JM, Vasanawala SS, Lustig M. * ESPIRiT - An Eigenvalue Approach to Autocalibrating Parallel MRI: Where SENSE * meets GRAPPA. Magn Reson Med, 71:990-1001 (2014) * * Iyer S, Ong F, Lustig M. * Towards A Parameter Free ESPIRiT: Soft-Weighting For Robust Coil Sensitivity Estimation. * Presented in the session: "New Frontiers In Image Reconstruction" at ISMRM 2016. * http://www.ismrm.org/16/program_files/O86.htm * */ #include #include #include #include #include "num/multind.h" #include "num/fft.h" #include "num/flpmath.h" #include "num/linalg.h" #include "num/lapack.h" #include "num/casorati.h" #include "num/rand.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/resize.h" #include "misc/debug.h" #include "misc/utils.h" #include "calib/calmat.h" #include "calib/cc.h" #include "calib/softweight.h" #include "calib.h" #ifdef USE_CUDA #include "calib/calibcu.h" #endif #if 0 #define CALMAT_SVD #endif #if 0 #define FLIP #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif static void eigen_herm3(int M, int N, float val[M], complex float matrix[N][N]) // ordering might be different to herm2 { complex float mout[M][N]; for (int li = 0; li < N; li++) for (int lj = 0; lj < li; lj++) matrix[lj][li] = conj(matrix[li][lj]); //mat_identity(M, N, mout); orthiter(M, N, 30, val, mout, matrix); for (int i = 0; i < M; i++) for (int j = 0; j < N; j++) matrix[i][j] = mout[i][j]; } static float scurve(float x) { if (x <= -1.) return 0.; if (x >= 1.) return 1.; return 0.5 * (1. + 2. * x / (1. + powf(x, 2.))); } static float crop_weight_function(float crth, float val) { return scurve((sqrtf(val) - crth) / (1. - crth)); } static float crop_thresh_function(float crth, float val) { return (val <= crth) ? 0. : 1.; } typedef float (*weight_function)(float crth, float val); static void crop_weight(const long dims[DIMS], complex float* ptr, weight_function fun, float crth, const complex float* map) { long xx = dims[0]; long yy = dims[1]; long zz = dims[2]; long cc = dims[3]; long mm = dims[4]; assert(DIMS > 5); assert(1 == md_calc_size(DIMS - 5, dims + 5)); for (long m = 0; m < mm; m++) { #pragma omp parallel for for (long k = 0; k < zz; k++) { for (long i = 0; i < yy; i++) { for (long j = 0; j < xx; j++) { float val = cabsf(map[((m * zz + k) * yy + i) * xx + j]); for (long c = 0; c < cc; c++) ptr[(((m * cc + c) * zz + k) * yy + i) * xx + j] *= fun(crth, val); } } } } } void crop_sens(const long dims[DIMS], complex float* ptr, bool soft, float crth, const complex float* map) { crop_weight(dims, ptr, soft ? crop_weight_function : crop_thresh_function, crth, map); } /** * sure_crop - This determines the crop-threshold to use as described in the talk: "Towards A Parameter * Free ESPIRiT: Soft-Weighting For Robust Coil Sensitivity Estimation". This was given at the * session: "New Frontiers In Image Reconstruction" at ISMRM 2016. * * Parameters: * var - Estimated variance in data. * evec_dims - The eigenvector dimensions. * evec_data - The eigenvectors. * eptr - The eigenvalues. * calreg_dims - Dimension of the calibration region. * calreg - Calibration data. */ static float sure_crop(float var, const long evec_dims[5], complex float* evec_data, complex float* eptr, const long calreg_dims[4], const complex float* calreg) { long num_maps = evec_dims[4]; // Construct low-resolution image long im_dims[5]; md_select_dims(5, 15, im_dims, evec_dims); complex float* im = md_alloc_sameplace(5, im_dims, CFL_SIZE, calreg); md_clear(5, im_dims, im, CFL_SIZE); md_resize_center(5, im_dims, im, calreg_dims, calreg, CFL_SIZE); ifftuc(5, im_dims, FFT_FLAGS, im, im); // Temporary vector for crop dimensions long cropdims[5]; md_select_dims(5, 15, cropdims, calreg_dims); cropdims[4] = num_maps; // Eigenvectors (M) complex float* M = md_alloc_sameplace(5, evec_dims, CFL_SIZE, calreg); md_copy(5, evec_dims, M, evec_data, CFL_SIZE); // Temporary eigenvector holder to hold low resolution maps complex float* LM = md_alloc_sameplace(5, evec_dims, CFL_SIZE, calreg); // Temporary holder for projection calreg complex float* TC = md_alloc_sameplace(5, calreg_dims, CFL_SIZE, calreg); // Temporary holder to hold low resolution calib maps complex float* CM = md_alloc_sameplace(5, cropdims, CFL_SIZE, calreg); // Eigenvalues (W) long W_dims[5]; md_select_dims(5, 23, W_dims, evec_dims); complex float* W = md_alloc_sameplace(5, W_dims, CFL_SIZE, calreg); md_copy(5, W_dims, W, eptr, CFL_SIZE); // Place holder for the inner product result complex float* ip = md_alloc_sameplace(5, W_dims, CFL_SIZE, calreg); // Place holder for the projection result complex float* proj = md_alloc_sameplace(5, im_dims, CFL_SIZE, calreg); // Place holder for divergence term long div_dims[5] = MD_INIT_ARRAY(5, 1); complex float* div = md_alloc_sameplace(5, div_dims, CFL_SIZE, calreg); // Calculating strides. long str1_ip[5]; long str2_ip[5]; long stro_ip[5]; md_calc_strides(5, str1_ip, im_dims, CFL_SIZE); md_calc_strides(5, str2_ip, evec_dims, CFL_SIZE); md_calc_strides(5, stro_ip, W_dims, CFL_SIZE); long str1_proj[5]; long str2_proj[5]; long stro_proj[5]; md_calc_strides(5, str1_proj, W_dims, CFL_SIZE); md_calc_strides(5, str2_proj, evec_dims, CFL_SIZE); md_calc_strides(5, stro_proj, im_dims, CFL_SIZE); long str1_div[5]; long str2_div[5]; long stro_div[5]; md_calc_strides(5, str1_div, evec_dims, CFL_SIZE); md_calc_strides(5, str2_div, evec_dims, CFL_SIZE); md_calc_strides(5, stro_div, div_dims, CFL_SIZE); long tdims_ip[5]; long tdims_proj[5]; for (unsigned int i = 0; i < 5; i++) { assert((im_dims[i] == evec_dims[i]) || (1 == im_dims[i]) || (1 == evec_dims[i])); assert(( W_dims[i] == evec_dims[i]) || (1 == W_dims[i]) || (1 == evec_dims[i])); tdims_ip[i] = (1 == im_dims[i]) ? evec_dims[i] : im_dims[i]; tdims_proj[i] = (1 == W_dims[i]) ? evec_dims[i] : W_dims[i]; } // Starting parameter sweep with SURE. float mse = -1; float old_mse = 0; float s = -0.1; float c = 0.99; long ctr1 = 0; long ctr2 = 0; debug_printf(DP_INFO, "---------------------------------------------\n"); debug_printf(DP_INFO, "| CTR1 | CTR2 | Crop | Est. MSE |\n"); debug_printf(DP_INFO, "---------------------------------------------\n"); while (fabs(s) > 1E-4) { ctr1 ++; while (c < 0.999 && c > 0.001 && (ctr2 <= 1 || mse < old_mse)) { ctr2 ++; md_clear(5, W_dims, ip, CFL_SIZE); md_clear(5, im_dims, proj, CFL_SIZE); md_clear(5, div_dims, div, CFL_SIZE); md_clear(5, evec_dims, M, CFL_SIZE); md_clear(5, evec_dims, LM, CFL_SIZE); md_clear(5, calreg_dims, TC, CFL_SIZE); md_copy(5, evec_dims, M, evec_data, CFL_SIZE); old_mse = mse; mse = 0; crop_weight(evec_dims, M, crop_thresh_function, c, W); // Cropping. md_zfmacc2(5, tdims_ip, stro_ip, ip, str1_ip, im, str2_ip, M); // Projection. md_zfmac2 (5, tdims_proj, stro_proj, proj, str1_proj, ip, str2_proj, M); fftuc(5, im_dims, FFT_FLAGS, proj, proj); // Low res proj img. md_resize_center(5, calreg_dims, TC, im_dims, proj, CFL_SIZE); md_resize_center(5, im_dims, proj, calreg_dims, TC, CFL_SIZE); ifftuc(5, im_dims, FFT_FLAGS, proj, proj); for (int jdx = 0; jdx < md_calc_size(5, im_dims); jdx++) mse += powf((float) (cabsf(im[jdx] - proj[jdx])), 2); fftuc(5, evec_dims, FFT_FLAGS, LM, M); // low-res maps . md_resize_center(5, cropdims, CM, evec_dims, LM, CFL_SIZE); md_resize_center(5, evec_dims, LM, cropdims, CM, CFL_SIZE); ifftuc(5, evec_dims, FFT_FLAGS, LM, LM); md_zfmacc2(5, evec_dims, stro_div, div, str1_div, LM, str2_div, LM); // Calc SURE div using low res maps. mse += (float) (2 * var * crealf(*div)); if (ctr2 == 1) debug_printf(DP_INFO, "| %4ld | %4ld | %0.4f | %0.12e |\n", ctr1, ctr2, c, mse); else debug_printf(DP_INFO, "| | %4ld | %0.4f | %0.12e |\n", ctr2, c, mse); c = c + s; } c -= s; ctr2 = 0; s = -s/2; c += s; } c = c + s; debug_printf(DP_INFO, "---------------------------------------------\n"); md_free(im); md_free(TC); md_free(CM); md_free(M); md_free(LM); md_free(W); md_free(ip); md_free(proj); md_free(div); debug_printf(DP_DEBUG1, "Calculated c: %.4f\n", c); return c; } void calone(const struct ecalib_conf* conf, const long cov_dims[4], complex float* imgcov, unsigned int SN, float svals[SN], const long calreg_dims[DIMS], const complex float* data) { assert(1 == md_calc_size(DIMS - 5, calreg_dims + 5)); #if 1 long nskerns_dims[5]; complex float* nskerns; compute_kernels(conf, nskerns_dims, &nskerns, SN, svals, calreg_dims, data); #else long channels = calreg_dims[3]; long kx = conf->kdims[0]; long ky = conf->kdims[1]; long kz = conf->kdims[2]; long nskerns_dims[5] = { kx, ky, kz, channels, 0 }; long N = md_calc_size(4, nskerns_dims); assert(N > 0); nskerns_dims[4] = N; complex float* nskerns = md_alloc(5, nskerns_dims, CFL_SIZE); long nr_kernels = channels; nskerns_dims[4] = channels; spirit_kernel(nskerns_dims, nskerns, calreg_dims, data); #endif compute_imgcov(cov_dims, imgcov, nskerns_dims, nskerns); md_free(nskerns); } /* calculate point-wise maps * */ void eigenmaps(const long out_dims[DIMS], complex float* optr, complex float* eptr, const complex float* imgcov2, const long msk_dims[3], const bool* msk, bool orthiter, bool ecal_usegpu) { #ifdef USE_CUDA if (ecal_usegpu) { //FIXME cuda version should be able to return sensitivities for a subset of image-space points assert(!msk); eigenmapscu(out_dims, optr, eptr, imgcov2); return; } #else assert(!ecal_usegpu); #endif long channels = out_dims[3]; long maps = out_dims[4]; assert(DIMS >= 5); assert(1 == md_calc_size(DIMS - 5, out_dims + 5)); assert(maps <= channels); long xx = out_dims[0]; long yy = out_dims[1]; long zz = out_dims[2]; float scale = 1.; // for some reason, not if (msk_dims) { assert(msk_dims[0] == xx); assert(msk_dims[1] == yy); assert(msk_dims[2] == zz); } md_clear(5, out_dims, optr, CFL_SIZE); #pragma omp parallel for collapse(3) for (long k = 0; k < zz; k++) { for (long j = 0; j < yy; j++) { for (long i = 0; i < xx; i++) { if (!msk || msk[i + xx * (j + yy * k)]) { float val[channels]; complex float cov[channels][channels]; complex float tmp[channels * (channels + 1) / 2]; for (long l = 0; l < channels * (channels + 1) / 2; l++) tmp[l] = imgcov2[((l * zz + k) * yy + j) * xx + i] / scale; unpack_tri_matrix(channels, cov, tmp); if (orthiter) eigen_herm3(maps, channels, val, cov); else lapack_eig(channels, val, cov); for (long u = 0; u < maps; u++) { long ru = (orthiter ? maps : channels) - 1 - u; for (long v = 0; v < channels; v++) optr[((((u * channels + v) * zz + k) * yy + j) * xx + i)] = cov[ru][v]; if (NULL != eptr) eptr[((u * zz + k) * yy + j) * xx + i] = val[ru]; } } } } } } void caltwo(const struct ecalib_conf* conf, const long out_dims[DIMS], complex float* out_data, complex float* emaps, const long in_dims[4], complex float* in_data, const long msk_dims[3], const bool* msk) { long xx = out_dims[0]; long yy = out_dims[1]; long zz = out_dims[2]; long xh = in_dims[0]; long yh = in_dims[1]; long zh = in_dims[2]; long channels = out_dims[3]; long cosize = channels * (channels + 1) / 2; assert(DIMS >= 5); assert(1 == md_calc_size(DIMS - 5, out_dims + 5)); assert(in_dims[3] == cosize); long cov_dims[4] = { xh, yh, zh, cosize }; long covbig_dims[4] = { xx, yy, zz, cosize }; assert(((xx == 1) && (xh == 1)) || (xx >= xh)); assert(((yy == 1) && (yh == 1)) || (yy >= yh)); assert(((zz == 1) && (zh == 1)) || (zz >= zh)); assert((1 == xh) || (0 == xh % 2)); assert((1 == yh) || (0 == yh % 2)); assert((1 == zh) || (0 == zh % 2)); complex float* imgcov2 = md_alloc(4, covbig_dims, CFL_SIZE); debug_printf(DP_DEBUG1, "Resize...\n"); sinc_zeropad(4, covbig_dims, imgcov2, cov_dims, in_data); debug_printf(DP_DEBUG1, "Point-wise eigen-decomposition...\n"); eigenmaps(out_dims, out_data, emaps, imgcov2, msk_dims, msk, conf->orthiter, conf->usegpu); md_free(imgcov2); } void calone_dims(const struct ecalib_conf* conf, long cov_dims[4], long channels) { long kx = conf->kdims[0]; long ky = conf->kdims[1]; long kz = conf->kdims[2]; cov_dims[0] = (1 == kx) ? 1 : (2 * kx); cov_dims[1] = (1 == ky) ? 1 : (2 * ky); cov_dims[2] = (1 == kz) ? 1 : (2 * kz); cov_dims[3] = channels * (channels + 1) / 2; } const struct ecalib_conf ecalib_defaults = { { 6, 6, 6 }, 0.001, -1, -1., false, false, 0.8, true, false, -1., false, true, -1., false}; void calib2(const struct ecalib_conf* conf, const long out_dims[DIMS], complex float* out_data, complex float* eptr, unsigned int SN, float svals[SN], const long calreg_dims[DIMS], const complex float* data, const long msk_dims[3], const bool* msk) { long channels = calreg_dims[3]; long maps = out_dims[4]; assert(calreg_dims[3] == out_dims[3]); assert(maps <= channels); assert(1 == md_calc_size(DIMS - 5, out_dims + 5)); assert(1 == md_calc_size(DIMS - 5, calreg_dims + 5)); complex float rot[channels][channels]; if (conf->rotphase) { // rotate the the phase with respect to the first principle component long scc_dims[DIMS] = MD_INIT_ARRAY(DIMS, 1); scc_dims[COIL_DIM] = channels; scc_dims[MAPS_DIM] = channels; scc(scc_dims, &rot[0][0], calreg_dims, data); } else { for (unsigned int i = 0; i < channels; i++) for (unsigned int j = 0; j < channels; j++) rot[i][j] = (i == j) ? 1. : 0.; } long cov_dims[4]; calone_dims(conf, cov_dims, channels); complex float* imgcov = md_alloc(4, cov_dims, CFL_SIZE); calone(conf, cov_dims, imgcov, SN, svals, calreg_dims, data); caltwo(conf, out_dims, out_data, eptr, cov_dims, imgcov, msk_dims, msk); /* Intensity and phase normalization similar as proposed * for adaptive combine (Walsh's method) in * Griswold et al., ISMRM 10:2410 (2002) */ if (conf->intensity) { debug_printf(DP_DEBUG1, "Normalize...\n"); /* I think the reason this works is because inhomogeneity usually * comes from only a few coil elements which are close. The l1-norm * is more resilient against such outliers. -- Martin */ normalizel1(DIMS, COIL_FLAG, out_dims, out_data); md_zsmul(DIMS, out_dims, out_data, out_data, sqrtf((float)channels)); } float c = (conf->crop >= 0.) ? conf->crop : sure_crop(conf->var, out_dims, out_data, eptr, calreg_dims, data); debug_printf(DP_DEBUG1, "Crop maps... (c = %.2f)\n", c); crop_sens(out_dims, out_data, conf->softcrop, c, eptr); debug_printf(DP_DEBUG1, "Fix phase...\n"); fixphase2(DIMS, out_dims, COIL_DIM, rot[0], out_data, out_data); md_free(imgcov); } void calib(const struct ecalib_conf* conf, const long out_dims[DIMS], complex float* out_data, complex float* eptr, unsigned int SN, float svals[SN], const long calreg_dims[DIMS], const complex float* data) { calib2(conf, out_dims, out_data, eptr, SN, svals, calreg_dims, data, NULL, NULL); } static void perturb(const long dims[2], complex float* vecs, float amt) { complex float* noise = md_alloc(2, dims, CFL_SIZE); md_gaussian_rand(2, dims, noise); for (long j = 0; j < dims[1]; j++) { float nrm = md_znorm(1, dims, noise + j * dims[0]); complex float val = amt / nrm; md_zsmul(1, dims, noise + j * dims[0], noise + j * dims[0], val); } md_zadd(2, dims, vecs, vecs, noise); for (long j = 0; j < dims[1]; j++) { float nrm = md_znorm(1, dims, vecs + j * dims[0]); complex float val = 1 / nrm; md_zsmul(1, dims, vecs + j * dims[0], vecs + j * dims[0], val); } md_free(noise); } static int number_of_kernels(const struct ecalib_conf* conf, unsigned int N, const float val[N]) { unsigned int n = 0; if (-1 != conf->numsv) { n = conf->numsv; assert(-1. == conf->percentsv); assert(-1. == conf->threshold); } else if (conf->percentsv != -1.) { n = (unsigned int)(N * conf->percentsv / 100.); assert(-1 == conf->numsv); assert(-1. == conf->threshold); } else { assert(-1 == conf->numsv); assert(-1. == conf->percentsv); for (unsigned int i = 0; i < N; i++) { if (val[i] / val[0] > sqrtf(conf->threshold)) n++; } } if (val[0] <= 0.) error("No signal.\n"); debug_printf(DP_DEBUG1, "Using %d/%ld kernels (%.2f%%, last SV: %f%s).\n", n, N, (float)n / (float)N * 100., (n > 0) ? (val[n - 1] / val[0]) : 1., conf->weighting ? ", weighted" : ""); float tr = 0.; for (unsigned int i = 0; i < N; i++) { tr += powf(val[i], 2.); debug_printf(DP_DEBUG3, "SVALS %f (%f)\n", val[i], val[i] / val[0]); } debug_printf(DP_DEBUG3, "\nTRACE: %f (%f)\n", tr, tr / (float)N); assert(n <= N); return n; } void compute_kernels(const struct ecalib_conf* conf, long nskerns_dims[5], complex float** nskerns_ptr, unsigned int SN, float val[SN], const long caldims[DIMS], const complex float* caldata) { assert(1 == md_calc_size(DIMS - 5, caldims + 5)); nskerns_dims[0] = conf->kdims[0]; nskerns_dims[1] = conf->kdims[1]; nskerns_dims[2] = conf->kdims[2]; nskerns_dims[3] = caldims[3]; long N = md_calc_size(4, nskerns_dims); assert(N > 0); nskerns_dims[4] = N; complex float* nskerns = md_alloc(5, nskerns_dims, CFL_SIZE); *nskerns_ptr = nskerns; PTR_ALLOC(complex float[N][N], vec); assert(NULL != val); assert(SN == N); debug_printf(DP_DEBUG1, "Build calibration matrix and SVD...\n"); #ifdef CALMAT_SVD calmat_svd(conf->kdims, N, *vec, val, caldims, caldata); if (conf->weighting) soft_weight_singular_vectors(N, conf->var, conf->kdims, caldims, val, val); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) #ifndef FLIP nskerns[i * N + j] = ((*vec)[j][i]) * (conf->weighting ? val[i] : 1.); #else nskerns[i * N + j] = ((*vec)[j][N - 1 - i]) * (conf->weighting ? val[N - 1 - i] : 1.); #endif #else covariance_function(conf->kdims, N, *vec, caldims, caldata); debug_printf(DP_DEBUG1, "Eigen decomposition... (size: %ld)\n", N); // we could apply Nystroem method here to speed it up float tmp_val[N]; lapack_eig(N, tmp_val, *vec); // reverse and square root, test for smaller null to avoid NaNs for (int i = 0; i < N; i++) val[i] = (tmp_val[N - 1 - i] < 0.) ? 0. : sqrtf(tmp_val[N - 1 - i]); if (conf->weighting) soft_weight_singular_vectors(N, conf-> var, conf->kdims, caldims, val, val); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) #ifndef FLIP nskerns[i * N + j] = (*vec)[N - 1 - i][j] * (conf->weighting ? val[i] : 1.); // flip #else nskerns[i * N + j] = (*vec)[i][j] * (conf->weighting ? val[N - 1 - i] : 1.); // flip #endif #endif if (conf->perturb > 0.) { long dims[2] = { N, N }; perturb(dims, nskerns, conf->perturb); } #ifndef FLIP nskerns_dims[4] = number_of_kernels(conf, N, val); #else nskerns_dims[4] = N - number_of_kernels(conf, N, val); #endif PTR_FREE(vec); } void compute_imgcov(const long cov_dims[4], complex float* imgcov, const long nskerns_dims[5], const complex float* nskerns) { debug_printf(DP_DEBUG1, "Zeropad...\n"); long xh = cov_dims[0]; long yh = cov_dims[1]; long zh = cov_dims[2]; long kx = nskerns_dims[0]; long ky = nskerns_dims[1]; long kz = nskerns_dims[2]; long channels = nskerns_dims[3]; long nr_kernels = nskerns_dims[4]; long imgkern_dims[5] = { xh, yh, zh, channels, nr_kernels }; complex float* imgkern1 = md_alloc(5, imgkern_dims, CFL_SIZE); complex float* imgkern2 = md_alloc(5, imgkern_dims, CFL_SIZE); md_resize_center(5, imgkern_dims, imgkern1, nskerns_dims, nskerns, CFL_SIZE); // resort array debug_printf(DP_DEBUG1, "FFT (juggling)...\n"); long istr[5]; long mstr[5]; long idim[5] = { xh, yh, zh, channels, nr_kernels }; long mdim[5] = { nr_kernels, channels, xh, yh, zh }; md_calc_strides(5, istr, idim, CFL_SIZE); md_calc_strides(5, mstr, mdim, CFL_SIZE); long m2str[5] = { mstr[2], mstr[3], mstr[4], mstr[1], mstr[0] }; ifftmod(5, imgkern_dims, FFT_FLAGS, imgkern1, imgkern1); ifft2(5, imgkern_dims, FFT_FLAGS, m2str, imgkern2, istr, imgkern1); float scalesq = (kx * ky * kz) * (xh * yh * zh); // second part for FFT scaling md_free(imgkern1); debug_printf(DP_DEBUG1, "Calculate Gram matrix...\n"); int cosize = channels * (channels + 1) / 2; assert(cov_dims[3] == cosize); #pragma omp parallel for collapse(3) for (int k = 0; k < zh; k++) { for (int j = 0; j < yh; j++) { for (int i = 0; i < xh; i++) { complex float gram[cosize]; gram_matrix2(channels, gram, nr_kernels, (const complex float (*)[nr_kernels])(imgkern2 + ((k * yh + j) * xh + i) * (channels * nr_kernels))); #ifdef FLIP // add (scaled) identity matrix for (int i = 0, l = 0; i < channels; i++) for (int j = 0; j <= i; j++, l++) gram[l] = ((i == j) ? (kx * ky * kz) : 0.) - gram[l]; #endif for (int l = 0; l < cosize; l++) imgcov[(((l * zh) + k) * yh + j) * xh + i] = gram[l] / scalesq; } } } md_free(imgkern2); } bart-0.5.00/src/calib/calib.h000066400000000000000000000044121353046746100156220ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __CALIB_H #define __CALIB_H #include "misc/cppwrap.h" #include "misc/mri.h" struct ecalib_conf { long kdims[3]; float threshold; int numsv; float percentsv; _Bool weighting; _Bool softcrop; float crop; _Bool orthiter; _Bool usegpu; float perturb; _Bool intensity; _Bool rotphase; float var; _Bool automate; }; extern const struct ecalib_conf ecalib_defaults; extern void calib(const struct ecalib_conf* conf, const long out_dims[DIMS], _Complex float* out_data, _Complex float* eptr, unsigned int SN, float svals[__VLA2(SN)], const long calreg_dims[DIMS], const _Complex float* calreg_data); extern void calib2(const struct ecalib_conf* conf, const long out_dims[DIMS], _Complex float* out_data, _Complex float* eptr, unsigned int SN, float svals[__VLA2(SN)], const long calreg_dims[DIMS], const _Complex float* data, const long msk_dims[3], const _Bool* msk); extern void eigenmaps(const long out_dims[DIMS], _Complex float* out_data, _Complex float* eptr, const _Complex float* imgcov, const long msk_dims[3], const _Bool* msk, _Bool orthiter, _Bool usegpu); extern void crop_sens(const long dims[DIMS], _Complex float* ptr, bool soft, float crth, const _Complex float* map); extern void calone_dims(const struct ecalib_conf* conf, long cov_dims[4], long channels); extern void calone(const struct ecalib_conf* conf, const long cov_dims[4], _Complex float* cov, unsigned int SN, float svals[__VLA2(SN)], const long calreg_dims[DIMS], const _Complex float* cal_data); extern void caltwo(const struct ecalib_conf* conf, const long out_dims[DIMS], _Complex float* out_data, _Complex float* emaps, const long in_dims[4], _Complex float* in_data, const long msk_dims[3], const _Bool* msk); extern void compute_imgcov(const long cov_dims[4], _Complex float* imgcov, const long nskerns_dims[5], const _Complex float* nskerns); extern void compute_kernels(const struct ecalib_conf* conf, long nskerns_dims[5], _Complex float** nskerns_ptr, unsigned int SN, float svals[__VLA2(SN)], const long caldims[DIMS], const _Complex float* caldata); #include "misc/cppwrap.h" #endif // __CALIB_H bart-0.5.00/src/calib/calibcu.cu000066400000000000000000000163171353046746100163410ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Dara Bahri * 2013 Martin Uecker */ #include #include #include #include #include #include #include #include #include #include #include "misc/mri.h" #include "num/multind.h" #include "num/flpmath.h" #include "calibcu.h" #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) extern "C" void error(const char* str, ...); #if 0 // pass &matrix[0][0] void eigen_hermcu(int N, float* eigenval, complex float* matrix) { culaInitialize(); assert(culaCheev('V', 'U', N, (culaFloatComplex*) matrix, N, (culaFloat*) eigenval) == culaNoError); culaShutdown(); } #endif static __device__ __host__ inline cuFloatComplex cuFloatComplexScale(cuFloatComplex a, float s) { cuFloatComplex c; c.x = s * a.x; c.y = s * a.y; return c; } static __device__ void gram_schmidtcu(int M, int N, cuFloatComplex* evals, cuFloatComplex* vecs) { cuFloatComplex val1; cuFloatComplex val2; for (int i = M-1; i >= 0; i--) { val1 = vecs[threadIdx.y + i*N]; __syncthreads(); for (int j = i+1; j <= M-1; j++) { val2 = vecs[threadIdx.y + j*N]; __syncthreads(); vecs[threadIdx.y + i*N] = cuCmulf(val1, cuConjf(val2)); __syncthreads(); if (threadIdx.y == 0) { cuFloatComplex tmp = make_cuFloatComplex(0.,0.); for (int k = 0; k < N; k++) tmp = cuCaddf(tmp, vecs[k + i*N]); vecs[i*N] = cuFloatComplexScale(tmp, -1.); } __syncthreads(); val1 = cuCaddf(val1, cuCmulf(val2, vecs[i*N])); __syncthreads(); } vecs[threadIdx.y + i*N] = cuCmulf(val1, cuConjf(val1)); __syncthreads(); if (threadIdx.y == 0) { cuFloatComplex tmp = make_cuFloatComplex(0.,0.); for (int k = 0; k < N; k++) tmp = cuCaddf(tmp, vecs[k + i*N]); evals[i] = make_cuFloatComplex(sqrt(cuCrealf(tmp)),0.); } __syncthreads(); vecs[threadIdx.y + i*N] = cuFloatComplexScale(val1, 1./cuCrealf(evals[i])); } } static __device__ inline void mat_mulcu(int M, int N, cuFloatComplex* A, cuFloatComplex* B, cuFloatComplex* C, int offset) { cuFloatComplex tmp; for (int i = 0; i < M; i++) { tmp = make_cuFloatComplex(0.,0.); for (int j = 0; j < N; j++) tmp = cuCaddf(tmp, cuCmulf(B[j + i*N], C[offset*N*N + threadIdx.y + j*N])); A[threadIdx.y + i*N] = tmp; } } static __global__ void eigenmapscu_kern(cuFloatComplex* in_filled, cuFloatComplex* in, cuFloatComplex* out, cuFloatComplex* vals, int iter, int x, int y, int z, int N, int M) { const int offset = blockIdx.x * blockDim.x + threadIdx.x; if (offset > x*y*z-1) return; extern __shared__ cuFloatComplex sdata[]; cuFloatComplex *tmp1, *tmp2, *evals; tmp1 = sdata + threadIdx.x * (2*M*N + M); tmp2 = tmp1 + M*N; evals = tmp2 + M*N; if (threadIdx.y == 0) { int l = 0; for (int i = 0; i < N; i++) { for (int j = 0; j <= i; j++) in_filled[offset*N*N + i*N + j] = in[offset + (l++)*x*y*z]; for (int j = 0; j < i; j++) in_filled[offset*N*N + j*N + i] = cuConjf(in_filled[offset*N*N + i*N + j]); } } __syncthreads(); for (int i = 0; i < M; i++) tmp1[threadIdx.y + i*N] = (threadIdx.y == i) ? make_cuFloatComplex(1.,0.) : make_cuFloatComplex(0.,0.); __syncthreads(); for (int i = 0; i < iter; i++) { for (int j = 0; j < M; j++) tmp2[threadIdx.y + j*N] = tmp1[threadIdx.y + j*N]; __syncthreads(); mat_mulcu(M, N, tmp1, tmp2, in_filled, offset); __syncthreads(); gram_schmidtcu(M, N, evals, tmp1); __syncthreads(); } for (int i = 0; i < M; i++) out[offset + (i*N + threadIdx.y)*x*y*z] = tmp1[N * (M-1-i) + threadIdx.y]; if (threadIdx.y == 0) if (vals) for (int i = 0; i < M; i++) vals[offset + i*x*y*z] = evals[M-1-i]; } void eigenmapscu(const long dims[5], _Complex float* optr, _Complex float* eptr, const _Complex float* imgcov2) { const int iter = 30; const int x = (int) dims[0]; const int y = (int) dims[1]; const int z = (int) dims[2]; const int N = (int) dims[3]; const int M = (int) dims[4]; assert(M <= N); long imgcov2_dims[5]; md_select_dims(5, ~(COIL_FLAG|MAPS_FLAG), imgcov2_dims, dims); imgcov2_dims[3] = N * (N + 1) / 2; long eptr_dims[5]; md_select_dims(5, ~COIL_FLAG, eptr_dims, dims); long imgcov2_df_dims[5]; md_select_dims(5, ~(COIL_FLAG|MAPS_FLAG), imgcov2_df_dims, dims); imgcov2_df_dims[3] = N * N; printf("CUDA Pointwise Eigendecomposition...\n"); cuFloatComplex* optr_device = (cuFloatComplex*)md_alloc_gpu(5, dims, sizeof(cuFloatComplex)); cuFloatComplex* imgcov2_device = (cuFloatComplex*)md_alloc_gpu(5, imgcov2_dims, sizeof(cuFloatComplex)); cuFloatComplex* imgcov2_device_filled = (cuFloatComplex*)md_alloc_gpu(5, imgcov2_df_dims, sizeof(cuFloatComplex)); cuFloatComplex* eptr_device = (cuFloatComplex*)md_alloc_gpu(5, eptr_dims, sizeof(cuFloatComplex)); md_copy(5, imgcov2_dims, imgcov2_device, imgcov2, sizeof(cuFloatComplex)); struct cudaDeviceProp mycudaDeviceProperties; cudaGetDeviceProperties(&mycudaDeviceProperties, 0); const int maxSharedMemPerBlock = mycudaDeviceProperties.sharedMemPerBlock; const int maxThreadsPerBlock = mycudaDeviceProperties.maxThreadsPerBlock; const int memPerPoint = (2*M*N + M) * sizeof(cuFloatComplex); int pointsPerBlock = MIN(maxThreadsPerBlock/N, maxSharedMemPerBlock/memPerPoint); const int maxRegsPerBlock = mycudaDeviceProperties.regsPerBlock; const int maxCmemPerBlock = mycudaDeviceProperties.totalConstMem; // determined by --ptxas-options="-v". cmem is constant mem used for 1) kernel args, 2) user defined constants, 3) compiler-generated constants const int regsPerThread = 36; const int cmemPerThread = 108; pointsPerBlock = MIN(pointsPerBlock, maxRegsPerBlock / (N * regsPerThread)); pointsPerBlock = MIN(pointsPerBlock, maxCmemPerBlock / (N * cmemPerThread)); assert(pointsPerBlock > 0); dim3 threads(pointsPerBlock, N, 1); int numBlocks = (x*y*z + (pointsPerBlock-1)) / pointsPerBlock; dim3 blocks(numBlocks); // if numBlocks > ~65,000, need to distribute over x, y, z dims size_t sharedMem = memPerPoint * pointsPerBlock; eigenmapscu_kern<<>>(imgcov2_device_filled, imgcov2_device, optr_device, eptr_device, iter, x, y, z, N, M); cudaDeviceSynchronize(); cudaError_t cu_error = cudaGetLastError(); if (cu_error != cudaSuccess) { fprintf(stderr, "ERROR: %s\n", cudaGetErrorString(cu_error)); error("abort!"); } md_copy(5, dims, optr, optr_device, sizeof(_Complex float)); md_copy(5, eptr_dims, eptr, eptr_device, sizeof(_Complex float)); md_free(imgcov2_device); md_free(imgcov2_device_filled); md_free(optr_device); md_free(eptr_device); } bart-0.5.00/src/calib/calibcu.h000066400000000000000000000005631353046746100161550ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" extern void eigenmapscu(const long dims[5], _Complex float* optr, _Complex float* eptr, const _Complex float* imgcov2); #include "misc/cppwrap.h" bart-0.5.00/src/calib/calmat.c000066400000000000000000000130341353046746100160040ustar00rootroot00000000000000/* Copyright 2013-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2015 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/casorati.h" #include "num/lapack.h" #include "num/linalg.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "calmat.h" /** * Compute basic calibration matrix */ complex float* calibration_matrix(long calmat_dims[2], const long kdims[3], const long calreg_dims[4], const complex float* data) { long kernel_dims[4]; md_copy_dims(3, kernel_dims, kdims); kernel_dims[3] = calreg_dims[3]; casorati_dims(4, calmat_dims, kernel_dims, calreg_dims); complex float* cm = md_alloc_sameplace(2, calmat_dims, CFL_SIZE, data); long calreg_strs[4]; md_calc_strides(4, calreg_strs, calreg_dims, CFL_SIZE); casorati_matrix(4, kernel_dims, calmat_dims, cm, calreg_dims, calreg_strs, data); return cm; } /** * Compute calibration matrix - but mask out a specified patch shape */ complex float* calibration_matrix_mask(long calmat_dims[2], const long kdims[3], const complex float* msk, const long calreg_dims[4], const complex float* data) { complex float* tmp = calibration_matrix(calmat_dims, kdims, calreg_dims, data); if (NULL == msk) return tmp; long msk_dims[2]; md_select_dims(2, ~MD_BIT(0), msk_dims, calmat_dims); assert(md_calc_size(3, kdims) * calreg_dims[3] == md_calc_size(2, msk_dims)); long msk_strs[2]; md_calc_strides(2, msk_strs, msk_dims, CFL_SIZE); // mask out un-sampled samples... long calmat_strs[2]; md_calc_strides(2, calmat_strs, calmat_dims, CFL_SIZE); md_zmul2(2, calmat_dims, calmat_strs, tmp, calmat_strs, tmp, msk_strs, msk); return tmp; } /** * Compute pattern matrix - mask out a specified patch shape */ static complex float* pattern_matrix(long pcm_dims[2], const long kdims[3], const complex float* mask, const long calreg_dims[4], const complex float* data) { // estimate pattern long pat_dims[4]; md_select_dims(4, ~MD_BIT(COIL_DIM), pat_dims, calreg_dims); complex float* pattern = md_alloc_sameplace(4, pat_dims, CFL_SIZE, data); estimate_pattern(4, calreg_dims, COIL_FLAG, pattern, data); // compute calibration matrix of pattern complex float* pm = calibration_matrix_mask(pcm_dims, kdims, mask, pat_dims, pattern); md_free(pattern); return pm; } complex float* calibration_matrix_mask2(long calmat_dims[2], const long kdims[3], const complex float* mask, const long calreg_dims[4], const complex float* data) { long pcm_dims[2]; complex float* pm = pattern_matrix(pcm_dims, kdims, mask, calreg_dims, data); long pcm_strs[2]; md_calc_strides(2, pcm_strs, pcm_dims, CFL_SIZE); // number of samples for each patch long msk_dims[2]; md_select_dims(2, ~MD_BIT(1), msk_dims, pcm_dims); long msk_strs[2]; md_calc_strides(2, msk_strs, msk_dims, CFL_SIZE); complex float* msk = md_alloc(2, msk_dims, CFL_SIZE); md_clear(2, msk_dims, msk, CFL_SIZE); md_zfmacc2(2, pcm_dims, msk_strs, msk, pcm_strs, pm, pcm_strs, pm); md_free(pm); // fully sampled? md_zcmp2(2, msk_dims, msk_strs, msk, msk_strs, msk, (long[2]){ 0, 0 }, &(complex float){ /* pcm_dims[1] */ 15 }); // FIXME debug_printf(DP_DEBUG1, "%ld/%ld fully-sampled patches.\n", (long)pow(md_znorm(2, msk_dims, msk), 2.), pcm_dims[0]); complex float* tmp = calibration_matrix_mask(calmat_dims, kdims, mask, calreg_dims, data); // mask out incompletely sampled patches... long calmat_strs[2]; md_calc_strides(2, calmat_strs, calmat_dims, CFL_SIZE); md_zmul2(2, calmat_dims, calmat_strs, tmp, calmat_strs, tmp, msk_strs, msk); return tmp; } #if 0 static void circular_patch_mask(const long kdims[3], unsigned int channels, complex float mask[channels * md_calc_size(3, kdims)]) { long kpos[3] = { 0 }; long kcen[3]; for (unsigned int i = 0; i < 3; i++) kcen[i] = (1 == kdims[i]) ? 0 : (kdims[i] - 1) / 2; do { float dist = 0.; for (unsigned int i = 0; i < 3; i++) dist += (float)labs(kpos[i] - kcen[i]) / (float)kdims[i]; for (unsigned int c = 0; c < channels; c++) mask[((c * kdims[2] + kpos[2]) * kdims[1] + kpos[1]) * kdims[0] + kpos[0]] = (dist <= 0.5) ? 1 : 0; } while (md_next(3, kdims, 1 | 2 | 4, kpos)); } #endif void covariance_function(const long kdims[3], unsigned int N, complex float cov[N][N], const long calreg_dims[4], const complex float* data) { long calmat_dims[2]; #if 1 complex float* cm = calibration_matrix(calmat_dims, kdims, calreg_dims, data); #else long channels = calreg_dims[3]; complex float msk[channels * md_calc_size(3, kdims)]; circular_patch_mask(kdims, channels, msk); complex float* cm = calibration_matrix_mask2(calmat_dims, kdims, msk, calreg_dims, data); #endif unsigned int L = calmat_dims[0]; assert(N == calmat_dims[1]); gram_matrix(N, cov, L, MD_CAST_ARRAY2(const complex float, 2, calmat_dims, cm, 0, 1)); md_free(cm); } void calmat_svd(const long kdims[3], unsigned int N, complex float cov[N][N], float* S, const long calreg_dims[4], const complex float* data) { long calmat_dims[2]; complex float* cm = calibration_matrix(calmat_dims, kdims, calreg_dims, data); unsigned int L = calmat_dims[0]; assert(N == calmat_dims[1]); PTR_ALLOC(complex float[L][L], U); // initialize to zero in case L < N not all written to for (unsigned int i = 0; i < N; i++) S[i] = 0.; lapack_svd_econ(L, N, *U, cov, S, MD_CAST_ARRAY2(complex float, 2, calmat_dims, cm, 0, 1)); PTR_FREE(U); md_free(cm); } bart-0.5.00/src/calib/calmat.h000066400000000000000000000015531353046746100160140ustar00rootroot00000000000000 #include "misc/cppwrap.h" extern complex float* calibration_matrix(long calmat_dims[2], const long kdims[3], const long calreg_dims[4], const complex float* data); extern complex float* calibration_matrix_mask(long calmat_dims[2], const long kdims[3], const complex float* mask, const long calreg_dims[4], const complex float* data); extern complex float* calibration_matrix_mask2(long calmat_dims[2], const long kdims[3], const complex float* msk, const long calreg_dims[4], const complex float* data); #ifndef __cplusplus extern void covariance_function(const long kdims[3], unsigned int N, complex float cov[static N][N], const long calreg_dims[4], const complex float* data); extern void calmat_svd(const long kdims[3], unsigned int N, complex float cov[static N][N], float* S, const long calreg_dims[4], const complex float* data); #endif #include "misc/cppwrap.h" bart-0.5.00/src/calib/cc.c000066400000000000000000000142731353046746100151360ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2014 Martin Uecker * 2013 Dara Bahri * * * Huang F, Vijayakumar S, Li Y, Hertel S, Duensing GR. A software channel * compression technique for faster reconstruction with many channels. * Magn Reson Imaging 2008; 26:133-141. * * Buehrer M, Pruessmann KP, Boesiger P, Kozerke S. Array compression for MRI * with large coil arrays. Magn Reson Med 2007, 57: 1131–1139. * * Zhang T, Pauly JM, Vasanawala SS, Lustig M. Coil compression for * accelerated imaging with cartesian sampling. Magn Reson Med 2013; * 69:571-582. * * Bahri D, Uecker M, Lustig M. ESPIRiT-Based Coil Compression for * Cartesian Sampling, Annual Meeting ISMRM, Salt Lake City 2013, * In: Proc Intl Soc Mag Reson Med 21:2657 */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/lapack.h" #include "num/linalg.h" #include "misc/debug.h" #include "misc/mri.h" #include "calib/calib.h" #include "cc.h" void scc(const long out_dims[DIMS], complex float* out_data, const long caldims[DIMS], const complex float* cal_data) { int channels = caldims[COIL_DIM]; assert(1 == md_calc_size(3, out_dims)); assert(out_dims[COIL_DIM] == channels); assert(out_dims[MAPS_DIM] == channels); complex float tmp[channels][channels]; size_t csize = md_calc_size(3, caldims); gram_matrix(channels, tmp, csize, (const complex float (*)[csize])cal_data); float vals[channels]; lapack_eig(channels, vals, tmp); md_flip(DIMS, out_dims, MAPS_FLAG, out_data, tmp, CFL_SIZE); debug_printf(DP_DEBUG1, "Energy:"); float sum = 0.; for (int i = 0; i < channels; i++) sum += vals[i]; for (int i = 0; i < channels; i++) debug_printf(DP_DEBUG1, " %.3f", vals[channels - 1 - i] / sum); debug_printf(DP_DEBUG1, "\n"); } static void align1(int M, int N, complex float out[M][N], const complex float in1[M][N], const complex float in2[M][N]) { assert(M <= N); #if 1 complex float in1T[N][M]; complex float C[M][M]; complex float U[M][M]; complex float VH[M][M]; float S[M]; complex float P[M][M]; mat_adjoint(M, N, in1T, in1); // A_{x-1}^H mat_mul(M, N, M, C, in2, in1T); // C = A_{x} A_{x-1}^H // VH and U are switched here because SVD uses column-major arrays lapack_svd(M, M, VH, U, S, C); // U S V^H = C mat_mul(M, M, M, C, U, VH); // U V^H mat_adjoint(M, M, P, C); // P_x = V U^H mat_mul(M, M, N, out, P, in2); // A_{x} <- P_x A_{x} #else mat_copy(M, N, out, in2); #endif } static void align_ro2(const long dims[DIMS], int start, int end, complex float* odata, const complex float* idata) { int dir = (start < end) ? 1 : -1; long tmp_dims[DIMS]; md_select_dims(DIMS, ~READ_FLAG, tmp_dims, dims); complex float* tmp1 = md_alloc(DIMS, tmp_dims, CFL_SIZE); complex float* tmp2 = md_alloc(DIMS, tmp_dims, CFL_SIZE); complex float* tmp3 = md_alloc(DIMS, tmp_dims, CFL_SIZE); md_copy_block(DIMS, (long[DIMS]){ [READ_DIM] = start }, tmp_dims, tmp1, dims, idata, CFL_SIZE); if (dir) md_copy_block(DIMS, (long[DIMS]){ [READ_DIM] = start }, dims, odata, tmp_dims, tmp1, CFL_SIZE); for (int i = start; i != end - dir; i += dir) { md_copy_block(DIMS, (long[DIMS]){ [READ_DIM] = i + dir }, tmp_dims, tmp2, dims, idata, CFL_SIZE); align1(tmp_dims[MAPS_DIM], tmp_dims[COIL_DIM], MD_CAST_ARRAY2( complex float, DIMS, tmp_dims, tmp3, COIL_DIM, MAPS_DIM), MD_CAST_ARRAY2(const complex float, DIMS, tmp_dims, tmp1, COIL_DIM, MAPS_DIM), MD_CAST_ARRAY2(const complex float, DIMS, tmp_dims, tmp2, COIL_DIM, MAPS_DIM)); md_copy(DIMS, tmp_dims, tmp1, tmp3, CFL_SIZE); md_copy_block(DIMS, (long[DIMS]){ [READ_DIM] = i + dir }, dims, odata, tmp_dims, tmp3, CFL_SIZE); } md_free(tmp1); md_free(tmp2); md_free(tmp3); } void align_ro(const long dims[DIMS], complex float* odata, const complex float* idata) { int ro = dims[READ_DIM]; assert(ro > 1); #if 1 align_ro2(dims, 0, ro, odata, idata); #else #pragma omp parallel sections { #pragma omp section align_ro2(dims, ro / 2, ro, odata, idata); #pragma omp section align_ro2(dims, ro / 2, -1, odata, idata); } #endif } void gcc(const long out_dims[DIMS], complex float* out_data, const long caldims[DIMS], const complex float* cal_data) { int ro = out_dims[READ_DIM]; // zero pad calibration region along readout and FFT long tmp_dims[DIMS]; md_copy_dims(DIMS, tmp_dims, caldims); tmp_dims[READ_DIM] = ro; complex float* tmp = md_alloc(DIMS, tmp_dims, CFL_SIZE); md_resize_center(DIMS, tmp_dims, tmp, caldims, cal_data, CFL_SIZE); ifftuc(DIMS, tmp_dims, READ_FLAG, tmp, tmp); // apply scc at each readout location long tmp2_dims[DIMS]; md_select_dims(DIMS, ~READ_FLAG, tmp2_dims, tmp_dims); long out2_dims[DIMS]; md_select_dims(DIMS, ~READ_FLAG, out2_dims, out_dims); #pragma omp parallel for for (int i = 0; i < ro; i++) { complex float* tmp2 = md_alloc(DIMS, tmp2_dims, CFL_SIZE); complex float* out2 = md_alloc(DIMS, out2_dims, CFL_SIZE); long pos[DIMS] = { [READ_DIM] = i }; md_copy_block(DIMS, pos, tmp2_dims, tmp2, tmp_dims, tmp, CFL_SIZE); scc(out2_dims, out2, tmp2_dims, tmp2); md_copy_block(DIMS, pos, out_dims, out_data, out2_dims, out2, CFL_SIZE); md_free(out2); md_free(tmp2); } md_free(tmp); } void ecc(const long out_dims[DIMS], complex float* out_data, const long caldims[DIMS], const complex float* cal_data) { int channels = caldims[COIL_DIM]; assert(1 == out_dims[PHS1_DIM]); assert(1 == out_dims[PHS2_DIM]); assert(out_dims[COIL_DIM] == channels); assert(out_dims[MAPS_DIM] == channels); struct ecalib_conf conf = ecalib_defaults; conf.threshold = 0.001; conf.crop = 0.; conf.kdims[0] = 6; conf.kdims[1] = 1; conf.kdims[2] = 1; // conf.numsv = L; conf.weighting = false; conf.orthiter = false; conf.perturb = 0.; long map_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, map_dims, out_dims); complex float* emaps = md_alloc(DIMS, map_dims, CFL_SIZE); int K = conf.kdims[0] * caldims[COIL_DIM]; float svals[K]; calib(&conf, out_dims, out_data, emaps, K, svals, caldims, cal_data); md_free(emaps); } bart-0.5.00/src/calib/cc.h000066400000000000000000000007621353046746100151410ustar00rootroot00000000000000 #include "misc/mri.h" extern void scc(const long out_dims[DIMS], complex float* out_data, const long caldims[DIMS], const complex float* cal_data); extern void gcc(const long out_dims[DIMS], complex float* out_data, const long caldims[DIMS], const complex float* cal_data); extern void ecc(const long out_dims[DIMS], complex float* out_data, const long caldims[DIMS], const complex float* cal_data); extern void align_ro(const long dims[DIMS], complex float* odata, const complex float* idata); bart-0.5.00/src/calib/direct.c000066400000000000000000000037251353046746100160230ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker * * * McKenzie CA, Yeh EN, Ohliger MA, Price MD, Sodickson DK. Self-calibrating parallel * imaging with automatic coil sensitivity extraction. Magn Reson Med 2002; 47:529–538. */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/specfun.h" #include "misc/mri.h" #include "misc/misc.h" #include "direct.h" static double kaiser(double beta, int M, int n) { if (M == 1) return 1.; if (fabs((double)n / (double)M - 0.5) >= 0.5) return 0.; return bessel_i0(beta * sqrt(1. - pow(2. * (double)n / (double)M - 1., 2.))) / bessel_i0(beta); } void direct_calib(const long dims[5], complex float* sens, const long caldims[5], const complex float* data) { complex float* tmp = md_alloc(5, caldims, CFL_SIZE); assert(1 == caldims[4]); assert(1 == dims[4]); md_copy(5, caldims, tmp, data, CFL_SIZE); // apply Kaiser-Bessel Window beta=4 for (int z = 0; z < caldims[2]; z++) for (int y = 0; y < caldims[1]; y++) for (int x = 0; x < caldims[0]; x++) for (int c = 0; c < caldims[3]; c++) tmp[((c * caldims[2] + z) * caldims[1] + y) * caldims[0] + x] *= kaiser(4., caldims[2], z) * kaiser(4., caldims[1], y) * kaiser(4., caldims[0], x); md_resize_center(5, dims, sens, caldims, tmp, CFL_SIZE); ifftc(5, dims, 7, sens, sens); long dims1[5]; md_select_dims(5, ~MD_BIT(COIL_DIM), dims1, dims); complex float* img = md_alloc(5, dims1, CFL_SIZE); md_zrss(5, dims, COIL_FLAG, img, sens); #if 1 long T = md_calc_size(5, dims1); for (int i = 0; i < T; i++) for (int j = 0; j < dims[COIL_DIM]; j++) sens[j * T + i] *= (cabs(img[i]) == 0.) ? 0. : (1. / cabs(img[i])); #endif md_free(img); } bart-0.5.00/src/calib/direct.h000066400000000000000000000004761353046746100160300ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ extern void direct_calib(const long dims[5], _Complex float* sens, const long caldims[5], const _Complex float* data); bart-0.5.00/src/calib/estvar.c000066400000000000000000000204101353046746100160430ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Siddharth Iyer */ #include #include #include #include #include #include #include #include "num/rand.h" #include "num/multind.h" #include "num/lapack.h" #include "misc/debug.h" #include "misc/misc.h" #include "calib/calib.h" #include "calib/calmat.h" #include "estvar.h" /** * noise_calreg - This uses the dimension of the calibration * region to create a new "calibration region" * with each entry being iid standard normal * (or Gaussian) samples. * * Parameters: * T - Product of all the dimensions of the calibration * region. * ncalreg - Pointer to store the new calibration region to. */ static void noise_calreg(long T, complex float* ncalreg) { float spike = 1; float stdev = 1.f/sqrtf(2.f); for (long idx = 0; idx < T; idx++) if (spike >= uniform_rand()) ncalreg[idx] = stdev * gaussian_rand(); } /** * file_name - This returns the name of file to read or write the simulated noise singular values to. * * Parameters: * kernel_dims - kernel dimensions. * calreg_dims - calibration region dimensions. */ static char* file_name(const long kernel_dims[3], const long calreg_dims[4]) { char PATH[] = "/save/nsv/"; char KERNEL[] = "KERNEL_"; char CALREG[] = "CALREG_"; char DAT[] = ".dat"; int space[] = {strlen(TOOLBOX_PATH), strlen(PATH), strlen(KERNEL), floor(log10(kernel_dims[0])) + 2, floor(log10(kernel_dims[1])) + 2, floor(log10(kernel_dims[2])) + 2, strlen(CALREG), floor(log10(calreg_dims[0])) + 2, floor(log10(calreg_dims[1])) + 2, floor(log10(calreg_dims[2])) + 2, floor(log10(calreg_dims[3])) + 1, strlen(DAT) + 1}; size_t total = 0; for (size_t idx = 0; idx < sizeof(space)/sizeof(int); idx ++) total += space[idx]; char* name = calloc(total, sizeof(char)); assert(NULL != name); sprintf(name, "%s%s%s%ldx%ldx%ld_%s%ldx%ldx%ldx%ld%s", TOOLBOX_PATH, PATH, KERNEL, kernel_dims[0], kernel_dims[1], kernel_dims[2], CALREG, calreg_dims[0], calreg_dims[1], calreg_dims[2], calreg_dims[3], DAT); return name; } /** * load_noise_sv - This loads the noise singular values if * previously simulated. * * Parameters: * kernel_dims[3] - kernel dimensions * calreg_dims[3] - calibration region dimensions * L - Number of elements in E. * E - Load simulated noise singular values to. */ static int load_noise_sv(const long kernel_dims[3], const long calreg_dims[4], long L, float* E) { char* name = file_name(kernel_dims, calreg_dims); FILE* fp = fopen(name, "rb"); if (!fp) { xfree(name); return 0; } int c = fread(E, sizeof(float), L, fp); assert(c == L); xfree(name); fclose(fp); return 1; } /** * save_noise_sv - This saves the simulated noise singular * values to use it again should the same * parameters are encountered again. * * Parameters: * kernel_dims[3] - kernel dimensions * calreg_dims[4] - calibration region dimensions * L - Number of elements in E. * E - Load simulated noise singular values to. */ static void save_noise_sv(const long kernel_dims[3], const long calreg_dims[4], long L, float* E) { char* name = file_name(kernel_dims, calreg_dims); FILE* fp = fopen(name, "wb"); if (!fp) { xfree(name); return; } fwrite(E, sizeof(float), L, fp); free(name); fclose(fp); } /** * nsv - This takes the singular value * decomposition of the Hankel matrix * constructed from a noise-only * calibration region. The noise is * distributed as zero-mean unit-variance * Gaussian noise. * * Parameters: * kernel_dims - The dimensions of the window that sweeps through the * calibration matrix. * calreg_dims - The calibration region dimensions. * L - The number of singular values. * E - Array to save noise singular values to. * num_iters - The number of iterations in order to get a better * estimate of the noise singular values. */ static void nsv(const long kernel_dims[3], const long calreg_dims[4], long L, float* E, long num_iters) { if (NULL != getenv("TOOLBOX_PATH") && 1 == load_noise_sv(kernel_dims, calreg_dims, L, E)) return; debug_printf(DP_DEBUG1, "NOTE: Running simulations to figure out noise singular values.\n"); debug_printf(DP_DEBUG1, " The simulation results are saved if TOOLBOX_PATH is set.\n"); long N = kernel_dims[0] * kernel_dims[1] * kernel_dims[2] * calreg_dims[3]; float tmpE[N]; long T = md_calc_size(4, calreg_dims) * sizeof(complex float); long ncalreg_dims[] = {T}; complex float* ncalreg = md_calloc(1, ncalreg_dims, sizeof(complex float)); noise_calreg(T, ncalreg); PTR_ALLOC(complex float[N][N], vec); covariance_function(kernel_dims, N, *vec, calreg_dims, ncalreg); lapack_eig(N, tmpE, *vec); for (int idx = 0; idx < L; idx ++) E[idx] = sqrtf(tmpE[N-idx-1]); for (long idx = 0; idx < num_iters - 1; idx ++) { noise_calreg(T, ncalreg); covariance_function(kernel_dims, N, *vec, calreg_dims, ncalreg); lapack_eig(N, tmpE, *vec); for (long jdx = 0; jdx < L; jdx ++) E[jdx] += sqrtf(tmpE[N-jdx-1]); } for (long idx = 0; idx < L; idx++) E[idx] /= num_iters; if (NULL != getenv("TOOLBOX_PATH")) save_noise_sv(kernel_dims, calreg_dims, L, E); PTR_FREE(vec); md_free(ncalreg); } /** * estimate_noise_variance - This function estimates the variance * of noise present in the calibration * region by fitting the last s^th singular * values of the noise simulation to the * Calibration matrix's singular values. * * Parameters: * L - This is the number of singular values, or the length * of S and E. * S - This is the singular values obtained from the singular * value decomposition of the Hankel matrix constructed * from the calibration data. * E - This is the noise singular values as constructed by * function: standard_normal_noise_sv */ static float estimate_noise_variance(long L, const float* S, const float* E) { float t = 0.f; float c = 0.f; // Counter to avoid zero singular values. long s = 4; // We fit the last one s^th singular values. int num = L/s; int start = L - num; for (long idx = 0; idx < num; idx ++) { if (isnan(S[start + idx]) || S[start + idx] <= 0 || isnan(E[start + idx]) || E[start + idx] <= 0) break; t += ((float)S[start + idx])/((float)E[start + idx]); c += 1.f; } return ((t * t)/(c * c))/1.21; //Scaling down since it works well in practice. } extern float estvar_sv(long L, const float S[L], const long kernel_dims[3], const long calreg_dims[4]) { float E[L]; nsv(kernel_dims, calreg_dims, L, E, 10); // Number of iterations set to 5. return estimate_noise_variance(L, S, E); } extern float estvar_calreg(const long kernel_dims[3], const long calreg_dims[4], const complex float* calreg) { // Calibration/Hankel matrix dimension. long calmat_dims[2] = {(calreg_dims[0] - kernel_dims[0] + 1) * (calreg_dims[1] - kernel_dims[1] + 1) * (calreg_dims[2] - kernel_dims[2] + 1), calreg_dims[3] * kernel_dims[0] * kernel_dims[1] * kernel_dims[2]}; long L = calmat_dims[0] > calmat_dims[1] ? calmat_dims[1] : calmat_dims[0]; long N = calmat_dims[1]; //Number of columns. float tmpE[N]; float S[L]; PTR_ALLOC(complex float[N][N], vec); covariance_function(kernel_dims, N, *vec, calreg_dims, calreg); lapack_eig(N, tmpE, *vec); PTR_FREE(vec); for (int idx = 0; idx < L; idx ++) S[idx] = sqrtf(tmpE[N-idx-1]); return estvar_sv(L, S, kernel_dims, calreg_dims); } extern float estvar_kspace(long N, const long kernel_dims[3], const long calib_size[3], const long kspace_dims[N], const complex float* kspace) { long calreg_dims[N]; complex float* calreg = NULL; calreg = extract_calib(calreg_dims, calib_size, kspace_dims, kspace, false); float variance = estvar_calreg(kernel_dims, calreg_dims, calreg); md_free(calreg); return variance; } bart-0.5.00/src/calib/estvar.h000066400000000000000000000032161353046746100160550ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Siddharth Iyer */ #ifndef __ESTVAR_H #define __ESTVAR_H #define TOOLBOX_PATH getenv("TOOLBOX_PATH") /** * estvar_sv - This estimates the variance of noise present in the * calibration region using the singular values of the * calibration matrix. * * Parameters: * L - Number of singular values. * S - Array of singular values. * kernel_dims - Kernel dimensions. * calreg_dims - Calibration region dimensions. */ extern float estvar_sv(long L, const float S[L], const long kernel_dims[3], const long calreg_dims[4]); /** * estvar_calreg - This estimates the variance of noise present in the * calibration region. * * Parameters: * kernel_dims - Kernel dimensions. * calreg_dims - Calibration region dimensions. * calreg - Calibration region. */ extern float estvar_calreg(const long kernel_dims[3], const long calreg_dims[4], const complex float* calreg); /** * estvar_kspace - This estimates the variance of noise present in kspace data. * * Parameters: * N - Total number of dimensions in a CFL file. * kernel_dims - Kernel dimensions. * calib_size - Size of the calibration region. * kspace_dims - Dimensions of input data. * kspace - Input kspace data. */ extern float estvar_kspace(long N, const long kernel_dims[3], const long calib_size[3], const long kspace_dims[N], const complex float* kspace); #endif bart-0.5.00/src/calib/softweight.c000066400000000000000000000064411353046746100167320ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015-2016 Siddharth Iyer * * Iyer S, Ong F, Lustig M. * Towards a Parameter­Free ESPIRiT: Soft­Weighting for Robust Coil Sensitivity Estimation * In Proceedings of ISMRM 2016. * * Candès E, Long C, Trzasko J. * Unbiased Risk Estimates for Singular Value Thresholding and Spectral Estimators. * IEEE Transactions on Signal Processing 61, no. 19 (2013): 4643­657. * */ #include #include #include #include #include #include #include "num/rand.h" #include "num/multind.h" #include "num/lapack.h" #include "misc/debug.h" #include "calib/estvar.h" #include "softweight.h" /* * divergence - Calculates the divergence of the spectral estimator for use in SURE as * proposed by Candès et al. * * Parameters: * N - Number of singular values. * S - Array of singular values. * calmat_dims - Dimension of the calibration matrix. * lambda - Soft-threshold to test. */ static float divergence(long N, const float S[N], const long calmat_dims[2], float lambda) { int idx, jdx; float div = 0; float abs_diff_bw_calmat_dims = labs(calmat_dims[0] - calmat_dims[1]); float s, s1, s2, t; for (idx = 0; idx < N; idx ++) { s = S[idx]; if (s == 0) continue; t = 1 - lambda/s; s1 = (s > lambda ? 1: 0) + 2 * abs_diff_bw_calmat_dims * (t > 0? t: 0); s2 = 0; for (jdx = 0; jdx < N; jdx++) { if (idx == jdx) continue; t = s - lambda; s2 += s * (t > 0? t: 0)/(s * s - S[jdx] * S[jdx]); } div += s1 + 4 * s2; } return div; } extern void soft_weight_singular_vectors(long N, float variance, const long kernel_dims[3], const long calreg_dims[4], const float S[N], float W[N]) { int idx = 0, jdx = 0; float t; long calmat_dims[2] = {(calreg_dims[0] - kernel_dims[0] + 1) * (calreg_dims[1] - kernel_dims[1] + 1) * (calreg_dims[2] - kernel_dims[2] + 1), kernel_dims[0] * kernel_dims[1] * kernel_dims[2] * calreg_dims[3]}; float Y = calmat_dims[0] * calmat_dims[1] * variance; float G = 0; for (jdx = 0; jdx < N; jdx++) { G += S[jdx] * S[jdx]; } debug_printf(DP_DEBUG1, "Using estimated variance: : %f\n", variance); float lambda = S[N-1]; float testMSE = 0; float testLambda = 0; float MSE = -Y + G + variance * divergence(N, S, calmat_dims, lambda); for (idx = 1; idx < N; idx++) { G = 0; testLambda = S[N-idx-1]; for (jdx = 0; jdx < N; jdx++) { t = S[jdx]; G += (t < testLambda? t * t : testLambda * testLambda); } testMSE = -Y + G + variance * divergence(N, S, calmat_dims, testLambda); if (testMSE < MSE) { MSE = testMSE; lambda = testLambda; } } debug_printf(DP_DEBUG1, "Soft threshold (Lambda): %f\n", lambda); for (int idx = 0; idx < N; idx++) { t = (S[idx] > 0) ?(S[idx] - lambda)/S[idx] : 0; W[idx] = (t > 0)? t : 0; } } bart-0.5.00/src/calib/softweight.h000066400000000000000000000026231353046746100167350ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015-2016 Siddharth Iyer * * Iyer S, Ong F, Lustig M. * Towards A Parameter­Free ESPIRiT: Soft­Weighting For Robust Coil Sensitivity Estimation. * In Proceedings Of ISMRM 2016. * * Candès E, Long C, Trzasko J. * Unbiased Risk Estimates for Singular Value Thresholding and Spectral Estimators. * IEEE Transactions on Signal Processing 61, no. 19 (2013): 4643­657. * */ #ifndef _SOFT_WEIGHT_H_ #define _SOFT_WEIGHT_H_ /** * soft_weight_singular_vectors - This returns weights for the singular vectors derived from the * soft-thresholding operator proposed by Candès et al., as seen * in "Towards a Parameter­Free ESPIRiT: Soft­Weighting for * Robust Coil Sensitivity Estimation." * * Parameters: * N - Number of singular values. * kernel_dims - Dimension of kernel. * calreg_dims - Calibration region dimensions. * S - Array of singular values. * W - Array to store weights to. */ extern void soft_weight_singular_vectors(long N, float var, const long kernel_dims[3], const long calreg_dims[4], const float S[N], float W[N]); #endif bart-0.5.00/src/calib/walsh.c000066400000000000000000000046401353046746100156640ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/linalg.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "calib/calmat.h" #include "walsh.h" void walsh(const long bsize[3], const long dims[DIMS], complex float* sens, const long caldims[DIMS], const complex float* data) { assert(1 == caldims[MAPS_DIM]); assert(1 == dims[MAPS_DIM]); int channels = caldims[COIL_DIM]; int cosize = channels * (channels + 1) / 2; assert(dims[COIL_DIM] == cosize); long dims1[DIMS]; md_copy_dims(DIMS, dims1, dims); dims1[COIL_DIM] = channels; long kdims[4]; kdims[0] = MIN(bsize[0], dims[0]); kdims[1] = MIN(bsize[1], dims[1]); kdims[2] = MIN(bsize[2], dims[2]); md_resize_center(DIMS, dims1, sens, caldims, data, CFL_SIZE); ifftc(DIMS, dims1, FFT_FLAGS, sens, sens); long odims[DIMS]; md_copy_dims(DIMS, odims, dims1); for (int i = 0; i < 3; i++) odims[i] = dims[i] + kdims[i] - 1; complex float* tmp = md_alloc(DIMS, odims, CFL_SIZE); #if 0 md_resizec(DIMS, odims, tmp, dims1, sens, CFL_SIZE); #else long cen[DIMS] = { 0 }; for (int i = 0; i < 3; i++) cen[i] = (odims[i] - dims[i] + 1) / 2; complex float* tmp1 = md_alloc(DIMS, odims, CFL_SIZE); md_circ_ext(DIMS, odims, tmp1, dims1, sens, CFL_SIZE); // md_resize(DIMS, odims, tmp1, dims1, sens, CFL_SIZE); md_circ_shift(DIMS, odims, cen, tmp, tmp1, CFL_SIZE); md_free(tmp1); #endif long calmat_dims[2]; complex float* cm = calibration_matrix(calmat_dims, kdims, odims, tmp); md_free(tmp); int xh = dims[0]; int yh = dims[1]; int zh = dims[2]; int pixels = calmat_dims[1] / channels; #pragma omp parallel for for (int k = 0; k < zh; k++) { complex float in[channels][pixels]; complex float cov[cosize]; for (int j = 0; j < yh; j++) { for (int i = 0; i < xh; i++) { for (int c = 0; c < channels; c++) for (int p = 0; p < pixels; p++) in[c][p] = cm[((((c * pixels + p) * zh) + k) * yh + j) * xh + i]; gram_matrix2(channels, cov, pixels, in); for (int l = 0; l < cosize; l++) sens[(((l * zh) + k) * yh + j) * xh + i] = cov[l]; } } } } bart-0.5.00/src/calib/walsh.h000066400000000000000000000005501353046746100156650ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/mri.h" extern void walsh(const long bsize[3], const long dims[DIMS], _Complex float* sens, const long caldims[DIMS], const _Complex float* data); bart-0.5.00/src/calmat.c000066400000000000000000000044751353046746100147430ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker */ #include #include #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "num/flpmath.h" #include "num/multind.h" #include "calib/calmat.h" static const char usage_str[] = " "; static const char help_str[] = "Compute calibration matrix."; int main_calmat(int argc, char* argv[]) { long calsize[3] = { 24, 24, 24 }; long kdims[3] = { 5, 5, 5 }; bool calcen = false; const struct opt_s opts[] = { OPT_VEC3('k', &kdims, "ksize", "kernel size"), OPT_VEC3('K', &kdims, "", "()"), OPT_VEC3('r', &calsize, "cal_size", "Limits the size of the calibration region."), OPT_VEC3('R', &calsize, "", "()"), OPT_SET('C', &calcen, "()"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); int N = DIMS; long ksp_dims[N]; complex float* in_data = load_cfl(argv[1], N, ksp_dims); assert(1 == ksp_dims[MAPS_DIM]); long cal_dims[N]; complex float* cal_data = NULL; if (!calcen) { cal_data = extract_calib(cal_dims, calsize, ksp_dims, in_data, false); } else { for (int i = 0; i < 3; i++) cal_dims[i] = (calsize[i] < ksp_dims[i]) ? calsize[i] : ksp_dims[i]; for (int i = 3; i < N; i++) cal_dims[i] = ksp_dims[i]; cal_data = md_alloc(N, cal_dims, CFL_SIZE); md_resize_center(N, cal_dims, cal_data, ksp_dims, in_data, CFL_SIZE); } for (int i = 0; i < 3; i++) if (1 == ksp_dims[i]) kdims[i] = 1; for (unsigned int i = 0; i < 3; i++) if ((1 == cal_dims[i]) && (1 != ksp_dims[i])) error("Calibration region not found!\n"); // FIXME: we should scale the data unmap_cfl(N, ksp_dims, in_data); long calmat_dims[N]; md_singleton_dims(N, calmat_dims); complex float* cm = calibration_matrix(calmat_dims, kdims, cal_dims, cal_data); md_free(cal_data); complex float* out_data = create_cfl(argv[2], N, calmat_dims); md_copy(N, calmat_dims, out_data, cm, CFL_SIZE); md_free(cm); unmap_cfl(N, calmat_dims, out_data); return 0; } bart-0.5.00/src/carg.c000066400000000000000000000017041353046746100144060ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Argument (phase angle).\n"; int main_carg(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, dims); complex float* out_data = create_cfl(argv[2], DIMS, dims); md_zarg(DIMS, dims, out_data, in_data); unmap_cfl(DIMS, dims, out_data); unmap_cfl(DIMS, dims, in_data); return 0; } bart-0.5.00/src/casorati.c000066400000000000000000000031631353046746100153000ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Jon Tamir */ #include #include #include #include #include "num/multind.h" #include "num/casorati.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "dim1 kern1 dim2 kern2 ... dimn kernn "; static const char help_str[] = "Casorati matrix with kernel (kern1, ..., kernn) along dimensions (dim1, ..., dimn).\n"; int main_casorati(int argc, char* argv[]) { cmdline(&argc, argv, 4, 100, usage_str, help_str, 0, NULL); num_init(); int count = argc - 3; assert((count > 0) && (count % 2 == 0)); long idims[DIMS]; long kdims[DIMS]; long odims[2]; complex float* idata = load_cfl(argv[argc - 2], DIMS, idims); md_copy_dims(DIMS, kdims, idims); for (int i = 0; i < count; i += 2) { unsigned int kdim = atoi(argv[i + 1]); unsigned int ksize = atoi(argv[i + 2]); assert(kdim < DIMS); assert(ksize >= 1); kdims[kdim] = ksize; } casorati_dims(DIMS, odims, kdims, idims); complex float* odata = create_cfl(argv[argc - 1], 2, odims); long istrs[DIMS]; md_calc_strides(DIMS, istrs, idims, CFL_SIZE); casorati_matrix(DIMS, kdims, odims, odata, idims, istrs, idata); unmap_cfl(DIMS, idims, idata); unmap_cfl(2, odims, odata); return 0; } bart-0.5.00/src/cc.c000066400000000000000000000101561353046746100140600ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2015,2017 Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2017 Martin Uecker */ #include #include #include #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "calib/cc.h" static const char usage_str[] = " |"; static const char help_str[] = "Performs coil compression."; int main_cc(int argc, char* argv[]) { long calsize[3] = { 24, 24, 24 }; bool proj = true; long P = -1; bool all = false; enum cc_type { SCC, GCC, ECC } cc_type = SCC; const struct opt_s opts[] = { OPT_LONG('p', &P, "N", "perform compression to N virtual channels"), OPT_CLEAR('M', &proj, "output compression matrix"), OPT_VEC3('r', &calsize, "S", "size of calibration region"), OPT_VEC3('R', &calsize, "", "(size of calibration region)"), OPT_SET('A', &all, "use all data to compute coefficients"), OPT_SELECT('S', enum cc_type, &cc_type, SCC, "type: SVD"), OPT_SELECT('G', enum cc_type, &cc_type, GCC, "type: Geometric"), OPT_SELECT('E', enum cc_type, &cc_type, ECC, "type: ESPIRiT"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); if ((-1 == P) && proj) { debug_printf(DP_WARN, "Use -M to output compression matrix.\n"); proj = false; } long in_dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, in_dims); assert(1 == in_dims[MAPS_DIM]); long channels = in_dims[COIL_DIM]; if (0 == P) P = channels; long out_dims[DIMS] = MD_INIT_ARRAY(DIMS, 1); out_dims[COIL_DIM] = channels; out_dims[MAPS_DIM] = channels; out_dims[READ_DIM] = (SCC == cc_type) ? 1 : in_dims[READ_DIM]; complex float* out_data = (proj ? anon_cfl : create_cfl)(argv[2], DIMS, out_dims); long caldims[DIMS]; complex float* cal_data = NULL; if (all) { md_copy_dims(DIMS, caldims, in_dims); cal_data = in_data; } else { cal_data = extract_calib(caldims, calsize, in_dims, in_data, false); } if (0. == md_znorm(DIMS, caldims, cal_data)) debug_printf(DP_WARN, "Empty calibration region.\n"); if (ECC == cc_type) debug_printf(DP_WARN, "Warning: ECC depends on a parameter choice rule for optimal results which is not implemented.\n"); switch (cc_type) { case SCC: scc(out_dims, out_data, caldims, cal_data); break; case GCC: gcc(out_dims, out_data, caldims, cal_data); break; case ECC: ecc(out_dims, out_data, caldims, cal_data); break; } if (!all) md_free(cal_data); if (proj) { debug_printf(DP_DEBUG1, "Compressing to %ld virtual coils...\n", P); long trans_dims[DIMS]; md_copy_dims(DIMS, trans_dims, in_dims); trans_dims[COIL_DIM] = P; complex float* trans_data = create_cfl(argv[2], DIMS, trans_dims); long fake_trans_dims[DIMS]; md_select_dims(DIMS, ~COIL_FLAG, fake_trans_dims, in_dims); fake_trans_dims[MAPS_DIM] = P; long out2_dims[DIMS]; md_copy_dims(DIMS, out2_dims, out_dims); out2_dims[MAPS_DIM] = P; if (SCC != cc_type) { complex float* in2_data = anon_cfl(NULL, DIMS, in_dims); ifftuc(DIMS, in_dims, READ_FLAG, in2_data, in_data); unmap_cfl(DIMS, in_dims, in_data); in_data = in2_data; complex float* out2 = anon_cfl(NULL, DIMS, out2_dims); align_ro(out2_dims, out2, out_data); unmap_cfl(DIMS, out_dims, out_data); out_data = out2; } md_zmatmulc(DIMS, fake_trans_dims, trans_data, out2_dims, out_data, in_dims, in_data); if (SCC != cc_type) { fftuc(DIMS, trans_dims, READ_FLAG, trans_data, trans_data); unmap_cfl(DIMS, out2_dims, out_data); } else { unmap_cfl(DIMS, out_dims, out_data); } unmap_cfl(DIMS, trans_dims, trans_data); unmap_cfl(DIMS, in_dims, in_data); } else { unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); } printf("Done.\n"); return 0; } bart-0.5.00/src/ccapply.c000066400000000000000000000063501353046746100151270ustar00rootroot00000000000000/* Copyright 2016-2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016-2017 Jonathan Tamir */ #include #include #include #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "calib/cc.h" static const char usage_str[] = " "; static const char help_str[] = "Apply coil compression forward/inverse operation."; int main_ccapply(int argc, char* argv[]) { bool forward = true; bool do_fft = true; long P = -1; enum cc_type { SCC, GCC, ECC } cc_type = SCC; const struct opt_s opts[] = { OPT_LONG('p', &P, "N", "perform compression to N virtual channels"), OPT_CLEAR('u', &forward, "apply inverse operation"), OPT_CLEAR('t', &do_fft, "don't apply FFT in readout"), OPT_SELECT('S', enum cc_type, &cc_type, SCC, "type: SVD"), OPT_SELECT('G', enum cc_type, &cc_type, GCC, "type: Geometric"), OPT_SELECT('E', enum cc_type, &cc_type, ECC, "type: ESPIRiT"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long in_dims[DIMS]; long cc_dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, in_dims); complex float* cc_data = load_cfl(argv[2], DIMS, cc_dims); assert(1 == in_dims[MAPS_DIM]); const long channels = cc_dims[COIL_DIM]; if (-1 == P) P = in_dims[COIL_DIM]; assert(cc_dims[MAPS_DIM] >= P && in_dims[COIL_DIM] >= P); long out_dims[DIMS] = MD_INIT_ARRAY(DIMS, 1); md_select_dims(DIMS, ~COIL_FLAG, out_dims, in_dims); out_dims[COIL_DIM] = forward ? P : channels; complex float* out_data = create_cfl(argv[3], DIMS, out_dims); // transpose for the matrix multiplication long trp_dims[DIMS]; if (forward) { debug_printf(DP_DEBUG1, "Compressing to %ld virtual coils...\n", P); md_transpose_dims(DIMS, COIL_DIM, MAPS_DIM, trp_dims, out_dims); trp_dims[MAPS_DIM] = out_dims[COIL_DIM]; } else { debug_printf(DP_DEBUG1, "Uncompressing channels...\n"); md_transpose_dims(DIMS, COIL_DIM, MAPS_DIM, trp_dims, in_dims); } long cc2_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, cc2_dims, cc_dims); cc2_dims[MAPS_DIM] = P; if (SCC != cc_type) { if (do_fft) { complex float* in2_data = anon_cfl(NULL, DIMS, in_dims); ifftuc(DIMS, in_dims, READ_FLAG, in2_data, in_data); unmap_cfl(DIMS, in_dims, in_data); in_data = in2_data; } complex float* cc2_data = anon_cfl(NULL, DIMS, cc2_dims); align_ro(cc2_dims, cc2_data, cc_data); unmap_cfl(DIMS, cc_dims, cc_data); cc_data = cc2_data; } if (forward) md_zmatmulc(DIMS, trp_dims, out_data, cc2_dims, cc_data, in_dims, in_data); else md_zmatmul(DIMS, out_dims, out_data, cc2_dims, cc_data, trp_dims, in_data); if (SCC != cc_type) { if (do_fft) fftuc(DIMS, out_dims, READ_FLAG, out_data, out_data); unmap_cfl(DIMS, cc2_dims, cc_data); } else { unmap_cfl(DIMS, cc_dims, cc_data); } unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); printf("Done.\n"); return 0; } bart-0.5.00/src/cdf97.c000066400000000000000000000026241353046746100144100ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/wavelet.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/opts.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Perform a wavelet (cdf97) transform.\n"; int main_cdf97(int argc, char* argv[]) { bool inv = false; const struct opt_s opts[] = { OPT_SET('i', &inv, "inverse"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int flags = atoi(argv[1]); long dims[DIMS]; complex float* idata = load_cfl(argv[2], DIMS, dims); complex float* odata = create_cfl(argv[3], DIMS, dims); md_copy(DIMS, dims, odata, idata, CFL_SIZE); unmap_cfl(DIMS, dims, idata); if (inv) { md_iresortz(DIMS, dims, flags, odata); md_icdf97z(DIMS, dims, flags, odata); } else { md_cdf97z(DIMS, dims, flags, odata); md_resortz(DIMS, dims, flags, odata); } unmap_cfl(DIMS, dims, odata); return 0; } bart-0.5.00/src/circshift.c000066400000000000000000000023271353046746100154520ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "dim shift "; static const char help_str[] = "Perform circular shift along {dim} by {shift} elements.\n"; int main_circshift(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); const int N = DIMS; long dims[N]; int dim = atoi(argv[1]); int shift = atoi(argv[2]); assert((0 <= dim) && (dim < N)); long center[N]; memset(center, 0, N * sizeof(long)); center[dim] = shift; complex float* idata = load_cfl(argv[3], N, dims); complex float* odata = create_cfl(argv[4], N, dims); md_circ_shift(N, dims, center, odata, idata, sizeof(complex float)); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/conj.c000066400000000000000000000016721353046746100144270ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2012 Martin Uecker */ #include #include #include #include #include #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Compute complex conjugate.\n"; int main_conj(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); const int N = 16; long dims[N]; complex float* idata = load_cfl(argv[1], N, dims); complex float* odata = create_cfl(argv[2], N, dims); md_zconj(N, dims, odata, idata); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/conv.c000066400000000000000000000024101353046746100144320ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2015 Martin Uecker */ #include #include #include "num/multind.h" #include "num/conv.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Performs a convolution along selected dimensions."; int main_conv(int argc, char* argv[]) { cmdline(&argc, argv, 4, 4, usage_str, help_str, 0, NULL); num_init(); unsigned int flags = atoi(argv[1]); unsigned int N = DIMS; long dims[N]; const complex float* in = load_cfl(argv[2], N, dims); long krn_dims[N]; const complex float* krn = load_cfl(argv[3], N, krn_dims); complex float* out = create_cfl(argv[4], N, dims); struct conv_plan* plan = conv_plan(N, flags, CONV_CYCLIC, CONV_SYMMETRIC, dims, dims, krn_dims, krn); conv_exec(plan, out, in); conv_free(plan); unmap_cfl(N, dims, out); unmap_cfl(N, krn_dims, krn); unmap_cfl(N, dims, in); return 0; } bart-0.5.00/src/copy.c000066400000000000000000000033661353046746100144520ustar00rootroot00000000000000/* Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016-2018 Martin Uecker */ #include #include #include "num/multind.h" #include "num/init.h" #include "misc/resize.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "[dim1 pos1 ... dimn posn] "; static const char help_str[] = "Copy an array (to a given position in the output file - which then must exist)."; int main_copy(int argc, char* argv[]) { const struct opt_s opts[] = { }; cmdline(&argc, argv, 2, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int N = DIMS; int count = argc - 3; assert((count >= 0) && (count % 2 == 0)); long in_dims[N]; long out_dims[N]; void* in_data = load_cfl(argv[argc - 2], N, in_dims); if (count > 0) { // get dimensions void* out_data = load_cfl(argv[argc - 1], N, out_dims); unmap_cfl(N, out_dims, out_data); } else { md_copy_dims(N, out_dims, in_dims); } void* out_data = create_cfl(argv[argc - 1], N, out_dims); long position[N]; for (unsigned int i = 0; i < N; i++) position[i] = 0; for (int i = 0; i < count; i += 2) { unsigned int dim = atoi(argv[i + 1]); long pos = atol(argv[i + 2]); assert(dim < N); assert((0 <= pos) && (pos < out_dims[dim])); position[dim] = pos; } md_copy_block(N, position, out_dims, out_data, in_dims, in_data, CFL_SIZE); unmap_cfl(N, in_dims, in_data); unmap_cfl(N, out_dims, out_data); return 0; } bart-0.5.00/src/cpyphs.c000066400000000000000000000017541353046746100150050ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Real value.\n"; int main_creal(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, dims); complex float* out_data = create_cfl(argv[2], DIMS, dims); md_zreal(DIMS, dims, out_data, in_data); unmap_cfl(DIMS, dims, out_data); unmap_cfl(DIMS, dims, in_data); return 0; } bart-0.5.00/src/crop.c000066400000000000000000000024121353046746100144320ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "dimension size "; static const char help_str[] = "Extracts a sub-array corresponding to the central part of {size} along {dimension}\n"; int main_crop(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); int N = DIMS; long in_dims[N]; long out_dims[N]; complex float* in_data = load_cfl(argv[3], N, in_dims); int dim = atoi(argv[1]); int count = atoi(argv[2]); assert(dim < N); assert(count >= 1); for (int i = 0; i < N; i++) out_dims[i] = in_dims[i]; out_dims[dim] = count; complex float* out_data = create_cfl(argv[4], N, out_dims); md_resize_center(N, out_dims, out_data, in_dims, in_data, sizeof(complex float)); unmap_cfl(N, in_dims, in_data); unmap_cfl(N, out_dims, out_data); return 0; } bart-0.5.00/src/delta.c000066400000000000000000000021041353046746100145560ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" static const char usage_str[] = "dims flags size out"; static const char help_str[] = "Kronecker delta.\n"; int main_delta(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); int N = atoi(argv[1]); long len = atoi(argv[3]); unsigned int flags = atoi(argv[2]); assert(N >= 0); long dims[N]; for (int i = 0; i < N; i++) dims[i] = MD_IS_SET(flags, i) ? len : 1; complex float* x = create_cfl(argv[4], N, dims); md_clear(N, dims, x, CFL_SIZE); md_fill_diag(N, dims, flags, x, &(complex float){ 1. }, CFL_SIZE); unmap_cfl(N, dims, x); return 0; } bart-0.5.00/src/dfwavelet/000077500000000000000000000000001353046746100153055ustar00rootroot00000000000000bart-0.5.00/src/dfwavelet/dfwavelet.c000066400000000000000000001171211353046746100174350ustar00rootroot00000000000000/* * Copyright 2013-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Frank Ong * 2013 Martin Uecker, Pat Virtue, and Mark Murphy * * * Ong F, Uecker M, Tariq U, Hsiao A, Alley MT, Vasanawala SS, Lustig M. * Robust 4D Flow Denoising using Divergence-free Wavelet Transform, * Magn Reson Med 2015; 73: 828-842. */ #define _GNU_SOURCE #include #include #include #include #include "num/multind.h" #include "misc/misc.h" #include "dfwavelet.h" #include "dfwavelet_impl.h" #ifdef USE_CUDA #include "dfwavelet_kernels.h" #endif #define str_eq(s1,s2) (!strcmp ((s1),(s2))) /******** Header *********/ static void dffwt3_cpu(struct dfwavelet_plan_s* plan, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn, data_t* in_vx,data_t* in_vy,data_t* in_vz); static void dfiwt3_cpu(struct dfwavelet_plan_s* plan, data_t* out_vx,data_t* out_vy,data_t* out_vz, data_t* in_wcdf1,data_t* in_wcdf2,data_t* in_wcn); static void dfsoftthresh_cpu(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn); static void dfwavthresh3_cpu(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh,data_t* out_vx,data_t* out_vy,data_t* out_vz,data_t* in_vx,data_t* in_vy,data_t* in_vz); void dflincomb_cpu(struct dfwavelet_plan_s* plan,data_t* wc1,data_t* wc2,data_t* wc3); void dfunlincomb_cpu(struct dfwavelet_plan_s* plan,data_t* wc1,data_t* wc2,data_t* wc3); static void fwt3_cpu(struct dfwavelet_plan_s* plan, data_t* out, data_t* in,int dir); static void iwt3_cpu(struct dfwavelet_plan_s* plan, data_t* out, data_t* in,int dir); static void circshift_cpu(struct dfwavelet_plan_s* plan, data_t *data); static void circunshift_cpu(struct dfwavelet_plan_s* plan, data_t *data); static void conv_down_3d(data_t *out, data_t *in, int size1, int skip1, int size2, int skip2, int size3, int skip3, scalar_t *filter, int filterLen); static void conv_up_3d(data_t *out, data_t *in, int size1, int skip1, int size2, int skip2, int size3, int skip3, scalar_t *filter, int filterLen); static void mult(data_t* in,scalar_t scalar,int maxInd); static void create_numLevels(struct dfwavelet_plan_s* plan); static void create_wavelet_sizes(struct dfwavelet_plan_s* plan); static void create_wavelet_filters(struct dfwavelet_plan_s* plan); static void get_noise_amp (struct dfwavelet_plan_s* plan); struct dfwavelet_plan_s* prepare_dfwavelet_plan(int numdims, long* imSize, long* minSize, data_t* res,int use_gpu) { struct dfwavelet_plan_s* plan = (struct dfwavelet_plan_s*) malloc(sizeof(struct dfwavelet_plan_s)); plan->use_gpu = use_gpu; plan->numdims = numdims; plan->imSize = (long*) malloc(sizeof(long)*numdims); plan->minSize = (long*) malloc(sizeof(long)*numdims); plan->res = (data_t*) malloc(sizeof(data_t)*numdims); plan->percentZero = -1; plan->noiseAmp = NULL; // Get imSize, numPixel, numdims plan->numPixel = 1; int i; for (i = 0; i < numdims; i++) { plan->imSize[i] = imSize[i]; plan->numPixel *= imSize[i]; plan->minSize[i] = minSize[i]; plan->res[i] = res[i]; } create_wavelet_filters(plan); create_numLevels(plan); create_wavelet_sizes(plan); plan->randShift = (int*) malloc(sizeof(int)*plan->numdims); memset(plan->randShift,0,sizeof(int)*plan->numdims); get_noise_amp(plan); return plan; } void dfwavelet_forward(struct dfwavelet_plan_s* plan, data_t* out_wcdf1, data_t* out_wcdf2, data_t* out_wcn, data_t* in_vx, data_t* in_vy, data_t* in_vz) { if(plan->use_gpu==0) dffwt3_cpu(plan,out_wcdf1,out_wcdf2,out_wcn,in_vx,in_vy,in_vz); #ifdef USE_CUDA if(plan->use_gpu==1) dffwt3_gpu(plan,out_wcdf1,out_wcdf2,out_wcn,in_vx,in_vy,in_vz); if(plan->use_gpu==2) dffwt3_gpuHost(plan,out_wcdf1,out_wcdf2,out_wcn,in_vx,in_vy,in_vz); #endif } void dfwavelet_inverse(struct dfwavelet_plan_s* plan, data_t* out_vx,data_t* out_vy,data_t* out_vz, data_t* in_wcdf1,data_t* in_wcdf2,data_t* in_wcn) { if(plan->use_gpu==0) dfiwt3_cpu(plan,out_vx,out_vy,out_vz,in_wcdf1,in_wcdf2,in_wcn); #ifdef USE_CUDA if(plan->use_gpu==1) dfiwt3_gpu(plan,out_vx,out_vy,out_vz,in_wcdf1,in_wcdf2,in_wcn); if(plan->use_gpu==2) dfiwt3_gpuHost(plan,out_vx,out_vy,out_vz,in_wcdf1,in_wcdf2,in_wcn); #endif } void dfsoft_thresh(struct dfwavelet_plan_s* plan, scalar_t dfthresh, scalar_t nthresh,data_t* wcdf1,data_t* wcdf2, data_t* wcn) { if(plan->use_gpu==0) dfsoftthresh_cpu(plan,dfthresh,nthresh,wcdf1,wcdf2,wcn); #ifdef USE_CUDA if(plan->use_gpu==1) dfsoftthresh_gpu(plan,dfthresh,nthresh,wcdf1,wcdf2,wcn); if(plan->use_gpu==2) dfsoftthresh_gpuHost(plan,dfthresh,nthresh,wcdf1,wcdf2,wcn); #endif } void dfwavelet_thresh(struct dfwavelet_plan_s* plan, scalar_t dfthresh, scalar_t nthresh,data_t* out_vx, data_t* out_vy, data_t* out_vz, data_t* in_vx,data_t* in_vy, data_t* in_vz) { if(plan->use_gpu==0) dfwavthresh3_cpu(plan,dfthresh,nthresh,out_vx,out_vy,out_vz, in_vx,in_vy,in_vz); #ifdef USE_CUDA if(plan->use_gpu==1) dfwavthresh3_gpu(plan,dfthresh,nthresh, out_vx,out_vy,out_vz, in_vx,in_vy,in_vz); if(plan->use_gpu==2) dfwavthresh3_gpuHost(plan,dfthresh,nthresh,out_vx,out_vy,out_vz,in_vx,in_vy,in_vz); #endif } static int dfrand_lim(unsigned int* state, int limit) { int divisor = RAND_MAX/(limit+1); int retval = 0; do { retval = rand_r(state) / divisor; } while (retval > limit); return retval; } void dfwavelet_new_randshift (struct dfwavelet_plan_s* plan) { int i; int maxShift = 1 << (plan->numLevels); for(i = 0; i < plan->numdims; i++) { // Generate random shift value between 0 and maxShift plan->randShift[i] = dfrand_lim(&plan->state, maxShift); } } void dfwavelet_clear_randshift (struct dfwavelet_plan_s* plan) { memset(plan->randShift, 0, plan->numdims*sizeof(int)); } void dfwavelet_free(struct dfwavelet_plan_s* plan) { free(plan->imSize); free(plan->minSize); free(plan->lod0); free(plan->lod1); free(plan->res); free(plan->waveSizes); free(plan->randShift); if (plan->noiseAmp!=NULL) free(plan->noiseAmp); free(plan); } ////////////// Private Functions ////////////// void dffwt3_cpu(struct dfwavelet_plan_s* plan, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn, data_t* in_vx,data_t* in_vy,data_t* in_vz) { fwt3_cpu(plan,out_wcdf1,in_vx,0); fwt3_cpu(plan,out_wcdf2,in_vy,1); fwt3_cpu(plan,out_wcn,in_vz,2); mult(out_wcdf1,1/plan->res[0],plan->numCoeff); mult(out_wcdf2,1/plan->res[1],plan->numCoeff); mult(out_wcn,1/plan->res[2],plan->numCoeff); dflincomb_cpu(plan,out_wcdf1,out_wcdf2,out_wcn); } void dfiwt3_cpu(struct dfwavelet_plan_s* plan, data_t* out_vx,data_t* out_vy,data_t* out_vz, data_t* in_wcdf1,data_t* in_wcdf2,data_t* in_wcn) { dfunlincomb_cpu(plan,in_wcdf1,in_wcdf2,in_wcn); mult(in_wcdf1,plan->res[0],plan->numCoeff); mult(in_wcdf2,plan->res[1],plan->numCoeff); mult(in_wcn,plan->res[2],plan->numCoeff); iwt3_cpu(plan,out_vx,in_wcdf1,0); iwt3_cpu(plan,out_vy,in_wcdf2,1); iwt3_cpu(plan,out_vz,in_wcn,2); } void dfsoftthresh_cpu(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh, data_t* wcdf1,data_t* wcdf2,data_t* wcn) { data_t* HxLyLz1 = wcdf1 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz2 = wcdf2 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz3 = wcn + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; int l; for (l = 1; l <= plan->numLevels; ++l){ HxLyLz1 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz2 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz3 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; } int dxNext = plan->waveSizes[0 + 3*plan->numLevels]; int dyNext = plan->waveSizes[1 + 3*plan->numLevels]; int dzNext = plan->waveSizes[2 + 3*plan->numLevels]; int blockSize = dxNext*dyNext*dzNext; int naInd = 0; for (l = plan->numLevels; l >= 1; --l) { dxNext = plan->waveSizes[0 + 3*l]; dyNext = plan->waveSizes[1 + 3*l]; dzNext = plan->waveSizes[2 + 3*l]; blockSize = dxNext*dyNext*dzNext; HxLyLz1 = HxLyLz1 - 7*blockSize; HxLyLz2 = HxLyLz2 - 7*blockSize; HxLyLz3 = HxLyLz3 - 7*blockSize; int bandInd; for (bandInd=0; bandInd<7*3;bandInd++) { data_t *subband; scalar_t lambda; if (bandInd<7) { subband = HxLyLz1 + bandInd*blockSize; lambda = dfthresh * plan->noiseAmp[naInd]; } else if (bandInd<14) { subband = HxLyLz2 + (bandInd-7)*blockSize; lambda = dfthresh * plan->noiseAmp[naInd]; } else { subband = HxLyLz3 + (bandInd-14)*blockSize; lambda = nthresh * plan->noiseAmp[naInd]; } // SoftThresh float const eps = 1.1921e-7f; #pragma omp parallel for for(int i = 0; i < blockSize; i++) { scalar_t norm = cabs(subband[i]); scalar_t red = norm - lambda; red = 0.5f*(red + fabs(red)); red = red / (norm + eps); subband[i] = red * subband[i]; } naInd++; } } } void dfwavthresh3_cpu(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh,data_t* out_vx,data_t* out_vy,data_t* out_vz,data_t* in_vx,data_t* in_vy,data_t* in_vz) { data_t *wcdf1,*wcdf2,*wcn; wcdf1 = (data_t*) malloc(sizeof(data_t)*plan->numCoeff); wcdf2 = (data_t*) malloc(sizeof(data_t)*plan->numCoeff); wcn = (data_t*) malloc(sizeof(data_t)*plan->numCoeff); dffwt3_cpu(plan, wcdf1,wcdf2,wcn,in_vx,in_vy,in_vz); dfsoftthresh_cpu(plan,dfthresh,nthresh,wcdf1,wcdf2,wcn); dfiwt3_cpu(plan,out_vx,out_vy,out_vz,wcdf1,wcdf2,wcn); free(wcdf1); free(wcdf2); free(wcn); } void dflincomb_cpu(struct dfwavelet_plan_s* plan,data_t* wc1,data_t* wc2,data_t* wc3) { data_t* HxLyLz1 = wc1 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz2 = wc2 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz3 = wc3 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; int l; for (l = 1; l <= plan->numLevels; ++l){ HxLyLz1 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz2 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz3 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; } int dxNext = plan->waveSizes[0 + 3*plan->numLevels]; int dyNext = plan->waveSizes[1 + 3*plan->numLevels]; int dzNext = plan->waveSizes[2 + 3*plan->numLevels]; int blockSize = dxNext*dyNext*dzNext; int i,j,k; for (l = plan->numLevels; l >= 1; --l) { dxNext = plan->waveSizes[0 + 3*l]; dyNext = plan->waveSizes[1 + 3*l]; dzNext = plan->waveSizes[2 + 3*l]; blockSize = dxNext*dyNext*dzNext; HxLyLz1 = HxLyLz1 - 7*blockSize; HxLyLz2 = HxLyLz2 - 7*blockSize; HxLyLz3 = HxLyLz3 - 7*blockSize; data_t* LxHyLz1 = HxLyLz1 + blockSize; data_t* HxHyLz1 = LxHyLz1 + blockSize; data_t* LxLyHz1 = HxHyLz1 + blockSize; data_t* HxLyHz1 = LxLyHz1 + blockSize; data_t* LxHyHz1 = HxLyHz1 + blockSize; data_t* HxHyHz1 = LxHyHz1 + blockSize; data_t* LxHyLz2 = HxLyLz2 + blockSize; data_t* HxHyLz2 = LxHyLz2 + blockSize; data_t* LxLyHz2 = HxHyLz2 + blockSize; data_t* HxLyHz2 = LxLyHz2 + blockSize; data_t* LxHyHz2 = HxLyHz2 + blockSize; data_t* HxHyHz2 = LxHyHz2 + blockSize; data_t* LxHyLz3 = HxLyLz3 + blockSize; data_t* HxHyLz3 = LxHyLz3 + blockSize; data_t* LxLyHz3 = HxHyLz3 + blockSize; data_t* HxLyHz3 = LxLyHz3 + blockSize; data_t* LxHyHz3 = HxLyHz3 + blockSize; data_t* HxHyHz3 = LxHyHz3 + blockSize; #pragma omp parallel for private(i,j,k) for (k=0;kwaveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz2 = wc2 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz3 = wc3 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; int l; for (l = 1; l <= plan->numLevels; ++l){ HxLyLz1 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz2 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz3 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; } int dxNext = plan->waveSizes[0 + 3*plan->numLevels]; int dyNext = plan->waveSizes[1 + 3*plan->numLevels]; int dzNext = plan->waveSizes[2 + 3*plan->numLevels]; int blockSize = dxNext*dyNext*dzNext; int i,j,k; for (l = plan->numLevels; l >= 1; --l) { dxNext = plan->waveSizes[0 + 3*l]; dyNext = plan->waveSizes[1 + 3*l]; dzNext = plan->waveSizes[2 + 3*l]; blockSize = dxNext*dyNext*dzNext; HxLyLz1 = HxLyLz1 - 7*blockSize; HxLyLz2 = HxLyLz2 - 7*blockSize; HxLyLz3 = HxLyLz3 - 7*blockSize; data_t* LxHyLz1 = HxLyLz1 + blockSize; data_t* HxHyLz1 = LxHyLz1 + blockSize; data_t* LxLyHz1 = HxHyLz1 + blockSize; data_t* HxLyHz1 = LxLyHz1 + blockSize; data_t* LxHyHz1 = HxLyHz1 + blockSize; data_t* HxHyHz1 = LxHyHz1 + blockSize; data_t* LxHyLz2 = HxLyLz2 + blockSize; data_t* HxHyLz2 = LxHyLz2 + blockSize; data_t* LxLyHz2 = HxHyLz2 + blockSize; data_t* HxLyHz2 = LxLyHz2 + blockSize; data_t* LxHyHz2 = HxLyHz2 + blockSize; data_t* HxHyHz2 = LxHyHz2 + blockSize; data_t* LxHyLz3 = HxLyLz3 + blockSize; data_t* HxHyLz3 = LxHyLz3 + blockSize; data_t* LxLyHz3 = HxHyLz3 + blockSize; data_t* HxLyHz3 = LxLyHz3 + blockSize; data_t* LxHyHz3 = HxLyHz3 + blockSize; data_t* HxHyHz3 = LxHyHz3 + blockSize; #pragma omp parallel for private(i,j,k) for (k=0;kwaveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; int l; for (l = 1; l <= plan->numLevels; ++l){ HxLyLz += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; } int dx = plan->imSize[0]; int dy = plan->imSize[1]; int dz = plan->imSize[2]; int dxNext = plan->waveSizes[0 + 3*plan->numLevels]; int dyNext = plan->waveSizes[1 + 3*plan->numLevels]; int dzNext = plan->waveSizes[2 + 3*plan->numLevels]; int blockSize = dxNext*dyNext*dzNext; data_t* LxLyLz = (data_t*) malloc(sizeof(data_t)*blockSize); data_t* tempz = (data_t*) malloc(sizeof(data_t)*dx*dy*dzNext); data_t* tempyz = (data_t*) malloc(sizeof(data_t)*dx*dyNext*dzNext); data_t* tempxyz = (data_t*) malloc(sizeof(data_t)*blockSize); // Assign Filters scalar_t *lodx,*lody,*lodz,*hidx,*hidy,*hidz; lodx = plan->lod0; lody = plan->lod0; lodz = plan->lod0; hidx = plan->hid0; hidy = plan->hid0; hidz = plan->hid0; if (dir==0) { lodx = plan->lod1; hidx = plan->hid1; } if (dir==1) { lody = plan->lod1; hidy = plan->hid1; } if (dir==2) { lodz = plan->lod1; hidz = plan->hid1; } for (l = plan->numLevels; l >= 1; --l) { dxNext = plan->waveSizes[0 + 3*l]; dyNext = plan->waveSizes[1 + 3*l]; dzNext = plan->waveSizes[2 + 3*l]; blockSize = dxNext*dyNext*dzNext; HxLyLz = HxLyLz - 7*blockSize; data_t* LxHyLz = HxLyLz + blockSize; data_t* HxHyLz = LxHyLz + blockSize; data_t* LxLyHz = HxHyLz + blockSize; data_t* HxLyHz = LxLyHz + blockSize; data_t* LxHyHz = HxLyHz + blockSize; data_t* HxHyHz = LxHyHz + blockSize; int dxy = dx*dy; int newdz = (dz + plan->filterLen-1) / 2; int newdy = (dy + plan->filterLen-1) / 2; int newdxy = dx*newdy; // Lz conv_down_3d(tempz, inImage, dz, dxy, dx, 1, dy, dx, lodz,plan->filterLen); // LyLz conv_down_3d(tempyz, tempz, dy, dx, dx, 1, newdz, dxy, lody,plan->filterLen); conv_down_3d(LxLyLz, tempyz, dx, 1, newdy, dx, newdz, newdxy, lodx,plan->filterLen); conv_down_3d(HxLyLz, tempyz, dx, 1, newdy, dx, newdz, newdxy, hidx,plan->filterLen); // HyLz conv_down_3d(tempyz, tempz, dy, dx, dx, 1, newdz, dxy, hidy,plan->filterLen); conv_down_3d(LxHyLz, tempyz, dx, 1, newdy, dx, newdz, newdxy, lodx,plan->filterLen); conv_down_3d(HxHyLz, tempyz, dx, 1, newdy, dx, newdz, newdxy, hidx,plan->filterLen); // Hz conv_down_3d(tempz, inImage, dz, dxy, dx, 1, dy, dx, hidz,plan->filterLen); // LyHz conv_down_3d(tempyz, tempz, dy, dx, dx, 1, newdz, dxy, lody,plan->filterLen); conv_down_3d(LxLyHz, tempyz, dx, 1, newdy, dx, newdz, newdxy, lodx,plan->filterLen); conv_down_3d(HxLyHz, tempyz, dx, 1, newdy, dx, newdz, newdxy, hidx,plan->filterLen); // HyHz conv_down_3d(tempyz, tempz, dy, dx, dx, 1, newdz, dxy, hidy,plan->filterLen); conv_down_3d(LxHyHz, tempyz, dx, 1, newdy, dx, newdz, newdxy, lodx,plan->filterLen); conv_down_3d(HxHyHz, tempyz, dx, 1, newdy, dx, newdz, newdxy, hidx,plan->filterLen); memcpy(tempxyz, LxLyLz, blockSize*sizeof(data_t)); inImage = tempxyz; dx = dxNext; dy = dyNext; dz = dzNext; } // Final LxLyLz memcpy(coeff, inImage, plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]*sizeof(data_t)); free(LxLyLz); free(tempz); free(tempyz); free(tempxyz); circunshift_cpu(plan,origInImage); } void iwt3_cpu(struct dfwavelet_plan_s* plan, data_t* outImage, data_t* coeff,int dir) { // Workspace dimensions int dxWork = plan->waveSizes[0 + 3*plan->numLevels]*2-1 + plan->filterLen-1; int dyWork = plan->waveSizes[1 + 3*plan->numLevels]*2-1 + plan->filterLen-1; int dzWork = plan->waveSizes[2 + 3*plan->numLevels]*2-1 + plan->filterLen-1; int dyWork2 = plan->waveSizes[1 + 3*(plan->numLevels-1)]*2-1 + plan->filterLen-1; int dzWork2 = plan->waveSizes[2 + 3*(plan->numLevels-1)]*2-1 + plan->filterLen-1; // Workspace data_t* tempyz = (data_t*) malloc(sizeof(data_t)*dxWork*dyWork2*dzWork2); data_t* tempz = (data_t*) malloc(sizeof(data_t)*dxWork*dyWork*dzWork2); data_t* tempFull = (data_t*) malloc(sizeof(data_t)*dxWork*dyWork*dzWork); int dx = plan->waveSizes[0]; int dy = plan->waveSizes[1]; int dz = plan->waveSizes[2]; // Assign Filters scalar_t *lorx,*lory,*lorz,*hirx,*hiry,*hirz; lorx = plan->lor0; lory = plan->lor0; lorz = plan->lor0; hirx = plan->hir0; hiry = plan->hir0; hirz = plan->hir0; if (dir==0) { lorx = plan->lor1; hirx = plan->hir1; } if (dir==1) { lory = plan->lor1; hiry = plan->hir1; } if (dir==2) { lorz = plan->lor1; hirz = plan->hir1; } memcpy(outImage, coeff, dx*dy*dz*sizeof(data_t)); data_t* HxLyLz = coeff + dx*dy*dz; int level; for (level = 1; level < plan->numLevels+1; ++level) { dx = plan->waveSizes[0 + 3*level]; dy = plan->waveSizes[1 + 3*level]; dz = plan->waveSizes[2 + 3*level]; int blockSize = dx*dy*dz; data_t* LxHyLz = HxLyLz + blockSize; data_t* HxHyLz = LxHyLz + blockSize; data_t* LxLyHz = HxHyLz + blockSize; data_t* HxLyHz = LxLyHz + blockSize; data_t* LxHyHz = HxLyHz + blockSize; data_t* HxHyHz = LxHyHz + blockSize; data_t* LxLyLz = outImage; int newdx = 2*dx-1 + plan->filterLen-1; int newdy = 2*dy-1 + plan->filterLen-1; int newdz = 2*dz-1 + plan->filterLen-1; int dxy = dx*dy; int newdxy = newdx*dy; int newnewdxy = newdx*newdy; memset(tempFull, 0, newnewdxy*newdz*sizeof(data_t)); memset(tempz, 0, newnewdxy*dz*sizeof(data_t)); memset(tempyz, 0, newdxy*dz*sizeof(data_t)); conv_up_3d(tempyz, LxLyLz, dx, 1, dy, dx, dz, dxy, lorx,plan->filterLen); conv_up_3d(tempyz, HxLyLz, dx, 1, dy, dx, dz, dxy, hirx,plan->filterLen); conv_up_3d(tempz, tempyz, dy, newdx, newdx, 1, dz, newdxy, lory,plan->filterLen); memset(tempyz, 0, newdxy*dz*sizeof(data_t)); conv_up_3d(tempyz, LxHyLz, dx, 1, dy, dx, dz, dxy, lorx,plan->filterLen); conv_up_3d(tempyz, HxHyLz, dx, 1, dy, dx, dz, dxy, hirx,plan->filterLen); conv_up_3d(tempz, tempyz, dy, newdx, newdx, 1, dz, newdxy, hiry,plan->filterLen); conv_up_3d(tempFull, tempz, dz, newnewdxy, newdx, 1, newdy, newdx, lorz,plan->filterLen); memset(tempz, 0, newnewdxy*dz*sizeof(data_t)); memset(tempyz, 0, newdxy*dz*sizeof(data_t)); conv_up_3d(tempyz, LxLyHz, dx, 1, dy, dx, dz, dxy, lorx,plan->filterLen); conv_up_3d(tempyz, HxLyHz, dx, 1, dy, dx, dz, dxy, hirx,plan->filterLen); conv_up_3d(tempz, tempyz, dy, newdx, newdx, 1, dz, newdxy, lory,plan->filterLen); memset(tempyz, 0, newdxy*dz*sizeof(data_t)); conv_up_3d(tempyz, LxHyHz, dx, 1, dy, dx, dz, dxy, lorx,plan->filterLen); conv_up_3d(tempyz, HxHyHz, dx, 1, dy, dx, dz, dxy, hirx,plan->filterLen); conv_up_3d(tempz, tempyz, dy, newdx, newdx, 1, dz, newdxy, hiry,plan->filterLen); conv_up_3d(tempFull, tempz, dz, newnewdxy, newdx, 1, newdy, newdx, hirz,plan->filterLen); // Crop center of workspace int dxNext = plan->waveSizes[0+3*(level+1)]; int dyNext = plan->waveSizes[1+3*(level+1)]; int dzNext = plan->waveSizes[2+3*(level+1)]; int dxyNext = dxNext*dyNext; dxWork = (2*dx-1 + plan->filterLen-1); dyWork = (2*dy-1 + plan->filterLen-1); dzWork = (2*dz-1 + plan->filterLen-1); int dxyWork = dxWork*dyWork; int xOffset = (int) ((dxWork - dxNext) / 2.0); int yOffset = (int) ((dyWork - dyNext) / 2.0); int zOffset = (int) ((dzWork - dzNext) / 2.0); int k,j; for (k = 0; k < dzNext; ++k){ for (j = 0; j < dyNext; ++j){ memcpy(outImage+j*dxNext + k*dxyNext, tempFull+xOffset + (yOffset+j)*dxWork + (zOffset+k)*dxyWork, dxNext*sizeof(data_t)); } } HxLyLz += 7*blockSize; } free(tempyz); free(tempz); free(tempFull); circunshift_cpu(plan,outImage); } void circshift_cpu(struct dfwavelet_plan_s* plan, data_t *data) { if (plan->randshift) dfwavelet_new_randshift(plan); // Return if no shifts int zeroShift = 1; int i; for (i = 0; i< plan->numdims; i++) { zeroShift &= (plan->randShift[i]==0); } if(zeroShift) { return; } // Copy data data_t* dataCopy = malloc(sizeof(data_t)*plan->numPixel); memcpy(dataCopy, data, plan->numPixel*sizeof(data_t)); if (plan->numdims==2) { int dx,dy,r0,r1,j,i,index,indexShifted; dx = plan->imSize[0]; dy = plan->imSize[1]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; #pragma omp parallel for private(index, j, i,indexShifted) for(j = 0; j < dy; j++) { for(i = 0; i < dx; i++) { index = i+j*dx; indexShifted = (((i+r0) + (j+r1)*dx)%(dx*dy)+dx*dy)%(dx*dy); data[indexShifted] = dataCopy[index]; } } } if (plan->numdims==3) { int dx,dy,dz,r0,r1,r2,k,j,i,index,indexShifted; dx = plan->imSize[0]; dy = plan->imSize[1]; dz = plan->imSize[2]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; r2 = plan->randShift[2]; #pragma omp parallel for private(index, k, j, i,indexShifted) for (k = 0; k < dz; k++) { for(j = 0; j < dy; j++) { for(i = 0; i < dx; i++) { index = i+j*dx+k*dx*dy; indexShifted = ((i+r0 + (j+r1)*dx + (k+r2)*dx*dy)%(dx*dy*dz)+(dx*dy*dz))%(dx*dy*dz); data[indexShifted] = dataCopy[index]; } } } } #pragma omp barrier free(dataCopy); } void circunshift_cpu(struct dfwavelet_plan_s* plan, data_t *data) { // Return if no shifts int zeroShift = 1; int i; for (i = 0; i< plan->numdims; i++) { zeroShift &= (plan->randShift[i]==0); } if(zeroShift) { return; } // Copy data data_t* dataCopy = malloc(sizeof(data_t)*plan->numPixel); memcpy(dataCopy, data, plan->numPixel*sizeof(data_t)); if (plan->numdims==2) { int dx,dy,r0,r1,j,i,index,indexShifted; dx = plan->imSize[0]; dy = plan->imSize[1]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; #pragma omp parallel for private(index, j, i,indexShifted) for(j = 0; j < dy; j++) { for(i = 0; i < dx; i++) { index = i+j*dx; indexShifted = (((i+r0) + (j+r1)*dx)%(dx*dy)+dx*dy)%(dx*dy); data[index] = dataCopy[indexShifted]; } } } if (plan->numdims==3) { int dx,dy,dz,r0,r1,r2,k,j,i,index,indexShifted; dx = plan->imSize[0]; dy = plan->imSize[1]; dz = plan->imSize[2]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; r2 = plan->randShift[2]; #pragma omp parallel for private(index, k, j, i,indexShifted) for (k = 0; k < dz; k++) { for(j = 0; j < dy; j++) { for(i = 0; i < dx; i++) { index = i+j*dx+k*dx*dy; indexShifted = ((i+r0 + (j+r1)*dx + (k+r2)*dx*dy)%(dx*dy*dz)+(dx*dy*dz))%(dx*dy*dz); data[index] = dataCopy[indexShifted]; } } } } free(dataCopy); } /********** Helper Function *********/ void conv_down_3d(data_t *out, data_t *in, int size1, int skip1, int size2, int skip2, int size3, int skip3, scalar_t *filter, int filterLen) { int outSize1 = (size1 + filterLen-1) / 2; // Adjust out skip 2 and 3 if needed int outSkip2; if(skip2 > skip1) { outSkip2 = outSize1*skip2/size1; } else { outSkip2 = skip2; } int outSkip3; if(skip3 > skip1) { outSkip3 = outSize1*skip3/size1; } else { outSkip3 = skip3; } int i32; #pragma omp parallel for for (i32 = 0; i32 < size2*size3; ++i32) { int i2 = i32 % size2; int i3 = i32 / size2; int i1; for (i1 = 0; i1 < outSize1; ++i1) { out[i3*outSkip3 + i2*outSkip2 + i1*skip1] = 0.0f; int k; for (k = 0; k < filterLen; ++k) { int out_i1 = 2*i1+1 - (filterLen-1) + k; if (out_i1 < 0) out_i1 = -out_i1-1; if (out_i1 >= size1) out_i1 = size1-1 - (out_i1-size1); out[i3*outSkip3 + i2*outSkip2 + i1*skip1] += in[i3*skip3 + i2*skip2 + out_i1*skip1] * filter[filterLen-1-k]; } } } } void conv_up_3d(data_t *out, data_t *in, int size1, int skip1, int size2, int skip2, int size3, int skip3, scalar_t *filter, int filterLen) { int outSize1 = 2*size1-1 + filterLen-1; // Adjust out skip 2 and 3 if needed int outSkip2; if(skip2 > skip1) { outSkip2 = outSize1*skip2/size1; } else { outSkip2 = skip2; } int outSkip3; if(skip3 > skip1) { outSkip3 = outSize1*skip3/size1; } else { outSkip3 = skip3; } int i32; #pragma omp parallel for for (i32 = 0; i32 < size2*size3; ++i32) { int i2 = i32 % size2; int i3 = i32 / size2; int i1; for (i1 = 0; i1 < outSize1; ++i1) { int k; for (k = (i1 - (filterLen-1)) & 1; k < filterLen; k += 2){ int in_i1 = (i1 - (filterLen-1) + k) >> 1; if (in_i1 >= 0 && in_i1 < size1) out[i3*outSkip3 + i2*outSkip2 + i1*skip1] += in[i3*skip3 + i2*skip2 + in_i1*skip1] * filter[filterLen-1-k]; } } } } void mult(data_t* in,scalar_t scale,int numMax) { int i; for(i=0; inumdims; int filterLen = plan->filterLen; int bandSize, l, minSize; plan->numLevels = 10000000; int d; for (d = 0; d < numdims; d++) { bandSize = plan->imSize[d]; minSize = plan->minSize[d]; l = 0; while (bandSize > minSize) { ++l; bandSize = (bandSize + filterLen - 1) / 2; } l--; plan->numLevels = (l < plan->numLevels) ? l : plan->numLevels; } } void create_wavelet_sizes(struct dfwavelet_plan_s* plan) { int numdims = plan->numdims; int filterLen = plan->filterLen; int numLevels = plan->numLevels; int numSubCoef; plan->waveSizes = (long*) malloc(sizeof(long)*numdims*(numLevels+2)); // Get number of subband per level, (3 for 2d, 7 for 3d) // Set the last bandSize to be imSize int d,l; int numSubband = 1; for (d = 0; dwaveSizes[d + numdims*(numLevels+1)] = plan->imSize[d]; numSubband <<= 1; } numSubband--; // Get numCoeff and waveSizes // Each bandSize[l] is (bandSize[l+1] + filterLen - 1)/2 plan->numCoeff = 0; for (l = plan->numLevels; l >= 1; --l) { numSubCoef = 1; for (d = 0; d < numdims; d++) { plan->waveSizes[d + numdims*l] = (plan->waveSizes[d + numdims*(l+1)] + filterLen - 1) / 2; numSubCoef *= plan->waveSizes[d + numdims*l]; } plan->numCoeff += numSubband*numSubCoef; if (l==1) plan->numCoarse = numSubCoef; } numSubCoef = 1; for (d = 0; d < numdims; d++) { plan->waveSizes[d] = plan->waveSizes[numdims+d]; numSubCoef *= plan->waveSizes[d]; } plan->numCoeff += numSubCoef; } /* All filter coefficients are obtained from http://wavelets.pybytes.com/ */ void create_wavelet_filters(struct dfwavelet_plan_s* plan) { int filterLen = 0; scalar_t* filter1, *filter2; filterLen = 6; // CDF 2.2 and CDF 3.1 Wavelet scalar_t cdf22[] = { 0.0,-0.17677669529663689,0.35355339059327379,1.0606601717798214,0.35355339059327379,-0.17677669529663689, 0.0,0.35355339059327379,-0.70710678118654757,0.35355339059327379,0.0,0.0, 0.0,0.35355339059327379,0.70710678118654757,0.35355339059327379,0.0,0.0, 0.0,0.17677669529663689,0.35355339059327379,-1.0606601717798214,0.35355339059327379,0.17677669529663689 }; scalar_t cdf31[] = { 0.0,-0.35355339059327379,1.0606601717798214,1.0606601717798214,-0.35355339059327379,0.0 , 0.0,-0.17677669529663689,0.53033008588991071,-0.53033008588991071,0.17677669529663689,0.0, 0.0,0.17677669529663689,0.53033008588991071,0.53033008588991071,0.17677669529663689,0.0, 0.0,-0.35355339059327379,-1.0606601717798214,1.0606601717798214,0.35355339059327379,0.0 }; filter1 = cdf22; filter2 = cdf31; // Allocate filters contiguously (for convenience) plan->filterLen = filterLen; plan->lod0 = (scalar_t*) malloc(sizeof(scalar_t) * 4 * filterLen); memcpy(plan->lod0, filter1, 4*filterLen*sizeof(scalar_t)); plan->lod1 = (scalar_t*) malloc(sizeof(scalar_t) * 4 * filterLen); memcpy(plan->lod1, filter2, 4*filterLen*sizeof(scalar_t)); plan->hid0 = plan->lod0 + 1*filterLen; plan->lor0 = plan->lod0 + 2*filterLen; plan->hir0 = plan->lod0 + 3*filterLen; plan->hid1 = plan->lod1 + 1*filterLen; plan->lor1 = plan->lod1 + 2*filterLen; plan->hir1 = plan->lod1 + 3*filterLen; } #ifndef M_PI #define M_PI 3.14159265358979323846 #endif static data_t drand() /* uniform distribution, (0..1] */ { return (rand()+1.0)/(RAND_MAX+1.0); } static void random_normal(data_t* in,int length) /* normal distribution, centered on 0, std dev 1 */ { int i; for (i=0;inoiseAmp==NULL) { // Generate Gaussian w/ mean=0, std=1 data data_t* vx,*vy,*vz; data_t* wcdf1,*wcdf2,*wcn; vx = (data_t*) malloc(sizeof(data_t)*plan->numPixel); vy = (data_t*) malloc(sizeof(data_t)*plan->numPixel); vz = (data_t*) malloc(sizeof(data_t)*plan->numPixel); random_normal(vx,plan->numPixel); random_normal(vy,plan->numPixel); random_normal(vz,plan->numPixel); wcdf1 = (data_t*) malloc(sizeof(data_t)*plan->numCoeff); wcdf2 = (data_t*) malloc(sizeof(data_t)*plan->numCoeff); wcn = (data_t*) malloc(sizeof(data_t)*plan->numCoeff); // Get Wavelet Coefficients int temp_use_gpu = plan->use_gpu; if (plan->use_gpu==1) plan->use_gpu = 2; dfwavelet_forward(plan,wcdf1,wcdf2,wcn,vx,vy,vz); plan->use_gpu = temp_use_gpu; // Get Noise Amp for each subband data_t* HxLyLz1 = wcdf1 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz2 = wcdf2 + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; data_t* HxLyLz3 = wcn + plan->waveSizes[0]*plan->waveSizes[1]*plan->waveSizes[2]; int l; for (l = 1; l <= plan->numLevels; ++l){ HxLyLz1 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz2 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; HxLyLz3 += 7*plan->waveSizes[0 + 3*l]*plan->waveSizes[1 + 3*l]*plan->waveSizes[2 + 3*l]; } int numBand = 7*plan->numLevels*3; plan->noiseAmp = (scalar_t*) malloc(sizeof(scalar_t)*numBand); int naInd = 0; for (l = plan->numLevels; l >= 1; --l) { int dxNext = plan->waveSizes[0 + 3*l]; int dyNext = plan->waveSizes[1 + 3*l]; int dzNext = plan->waveSizes[2 + 3*l]; int blockSize = dxNext*dyNext*dzNext; HxLyLz1 = HxLyLz1 - 7*blockSize; HxLyLz2 = HxLyLz2 - 7*blockSize; HxLyLz3 = HxLyLz3 - 7*blockSize; int bandInd; //#pragma omp parallel for private(bandInd) for (bandInd=0; bandInd<7*3;bandInd++) { data_t *subband; if (bandInd<7) { subband = HxLyLz1 + bandInd*blockSize; } else if (bandInd<14) { subband = HxLyLz2 + (bandInd-7)*blockSize; } else { subband = HxLyLz3 + (bandInd-14)*blockSize; } data_t sig = 0; data_t mean = 0; data_t mean_old; int i; for (i=0; inoiseAmp[naInd] = sig; naInd++; } } free(vx); free(vy); free(vz); free(wcdf1); free(wcdf2); free(wcn); } } bart-0.5.00/src/dfwavelet/dfwavelet.h000066400000000000000000000030161353046746100174370ustar00rootroot00000000000000/* * Copyright 2013-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __DFWAVELET_H #define __DFWAVELET_H #include "misc/cppwrap.h" struct dfwavelet_plan_s; extern struct dfwavelet_plan_s* prepare_dfwavelet_plan(int numdims, long* imSize, long* minSize_tr, _Complex float* res, int use_gpu); extern void dfwavelet_forward(struct dfwavelet_plan_s* plan, _Complex float* out_wcdf1, _Complex float* out_wcdf2, _Complex float* out_wcn, _Complex float* in_vx, _Complex float* in_vy, _Complex float* in_vz); extern void dfwavelet_inverse(struct dfwavelet_plan_s* plan, _Complex float* out_vx, _Complex float* out_vy, _Complex float* out_vz, _Complex float* in_wcdf1, _Complex float* in_wcdf2, _Complex float* in_wcn); extern void dfsoft_thresh(struct dfwavelet_plan_s* plan, float dfthresh, float nthresh, _Complex float* wcdf1, _Complex float* wcdf2, _Complex float* wcn); extern void dfwavelet_thresh(struct dfwavelet_plan_s* plan, float dfthresh, float nthresh,_Complex float* out_vx, _Complex float* out_vy, _Complex float* out_vz, _Complex float* in_vx,_Complex float* in_vy, _Complex float* in_vz); extern void dfwavelet_new_randshift(struct dfwavelet_plan_s* plan); extern void dfwavelet_clear_randshift(struct dfwavelet_plan_s* plan); extern void dfwavelet_free(struct dfwavelet_plan_s* plan); extern void print_plan(struct dfwavelet_plan_s* plan); #include "misc/cppwrap.h" #endif // __WAVELET_H bart-0.5.00/src/dfwavelet/dfwavelet_impl.h000066400000000000000000000027041353046746100204630ustar00rootroot00000000000000/* * Copyright 2013-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ /** * data_t is the type for input/output data, can be float/double or _Complex float/double. */ typedef _Complex float data_t; /** * scalar_t is the type for filter and scalers, can be float/double */ typedef float scalar_t; /** * Wavelet Plan struct * * @param imSize Input Image Size * @param numPixel Number of image pixels * @param numCoeff Number of wavelet coefficients * @param trDims Which dimensions we do wavelet transform * @param minSize_tr Minimum size for the scaling subband * @param waveSizes_tr Contains all wavelet subband sizes * */ struct dfwavelet_plan_s { int use_gpu; unsigned int state; int numdims; long* imSize; // Input Image Size long numPixel; // Number of image pixels long numCoeff; // Number of wavelet coefficients data_t* res; // Resolution scalar_t* noiseAmp; // Noise amplification for each subband scalar_t percentZero; long* minSize; // Minimum size for the scaling subband long numCoarse; long* waveSizes; // Contains all wavelet subband sizes int numLevels; int* randShift; _Bool randshift; // Filter parameters int filterLen; scalar_t* lod0; scalar_t* hid0; scalar_t* lor0; scalar_t* hir0; scalar_t* lod1; scalar_t* hid1; scalar_t* lor1; scalar_t* hir1; }; bart-0.5.00/src/dfwavelet/dfwavelet_kernels.cu000066400000000000000000001735141353046746100213550ustar00rootroot00000000000000/* * Copyright 2013-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Frank Ong, Martin Uecker, Pat Virtue, and Mark Murphy * frankong@berkeley.edu */ #include #include #include #include #include #include #include #include "num/multind.h" #include "dfwavelet_kernels.h" #include "dfwavelet_impl.h" # define _hdev_ __host__ __device__ // _data_t is the interal representation of data_t in CUDA // Must be float2/double2 for data_t=Complex float/double or float/double for data_t=float/double typedef float2 _data_t; // Float2 Operators inline _hdev_ float2 operator+ (float2 z1, float2 z2) { return make_float2 (z1.x + z2.x, z1.y + z2.y); } inline _hdev_ float2 operator- (float2 z1, float2 z2) { return make_float2 (z1.x - z2.x, z1.y - z2.y); } inline _hdev_ float2 operator* (float2 z1, float2 z2) { return make_float2 (z1.x*z2.x - z1.y*z2.y, z1.x*z2.y + z1.y*z2.x); } inline _hdev_ float2 operator* (float2 z1, float alpha) { return make_float2 (z1.x*alpha, z1.y*alpha); } inline _hdev_ float2 operator* (float alpha,float2 z1) { return make_float2 (z1.x*alpha, z1.y*alpha); } inline _hdev_ float2 operator/ (float alpha,float2 z1) { return make_float2 (1.f/z1.x, 1.f/z1.y); } inline _hdev_ void operator+= (float2 &z1, float2 z2) { z1.x += z2.x; z1.y += z2.y; } inline _hdev_ float abs(float2 z1) { return sqrt(z1.x*z1.x + z1.y*z1.y); } // Double2 Operators inline _hdev_ double2 operator+ (double2 z1, double2 z2) { return make_double2 (z1.x + z2.x, z1.y + z2.y); } inline _hdev_ double2 operator- (double2 z1, double2 z2) { return make_double2 (z1.x - z2.x, z1.y - z2.y); } inline _hdev_ double2 operator* (double2 z1, double2 z2) { return make_double2 (z1.x*z2.x - z1.y*z2.y, z1.x*z2.y + z1.y*z2.x); } inline _hdev_ double2 operator* (double2 z1, double alpha) { return make_double2 (z1.x*alpha, z1.y*alpha); } inline _hdev_ double2 operator* (double alpha,double2 z1) { return make_double2 (z1.x*alpha, z1.y*alpha); } inline _hdev_ double2 operator/ (double alpha,double2 z1) { return make_double2 (1.f/z1.x, 1.f/z1.y); } inline _hdev_ void operator+= (double2 &z1, double2 z2) { z1.x += z2.x; z1.y += z2.y; } inline _hdev_ double abs(double2 z1) { return sqrt(z1.x*z1.x + z1.y*z1.y); } /********** Macros ************/ #define cuda(Call) do { \ cudaError_t err = cuda ## Call ; \ if (err != cudaSuccess){ \ fprintf(stderr, "%s\n", cudaGetErrorString(err)); \ throw; \ } \ } while(0) #define cuda_sync() do{ \ cuda (DeviceSynchronize()); \ cuda (GetLastError()); \ } while(0) /********** Macros ************/ #define cuda(Call) do { \ cudaError_t err = cuda ## Call ; \ if (err != cudaSuccess){ \ fprintf(stderr, "%s\n", cudaGetErrorString(err)); \ throw; \ } \ } while(0) #define cuda_sync() do{ \ cuda (DeviceSynchronize()); \ cuda (GetLastError()); \ } while(0) // ############################################################################ // Headers // ############################################################################ static __global__ void cu_fwt3df_col(_data_t *Lx,_data_t *Hx,_data_t *in,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,scalar_t *lod,scalar_t *hid,int filterLen); static __global__ void cu_fwt3df_row(_data_t *Ly,_data_t *Hy,_data_t *in,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,scalar_t *lod,scalar_t *hid,int filterLen); static __global__ void cu_fwt3df_dep(_data_t *Lz,_data_t *Hz,_data_t *in,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,scalar_t *lod,scalar_t *hid,int filterLen); static __global__ void cu_iwt3df_dep(_data_t *out,_data_t *Lz,_data_t *Hz,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,int xOffset,int yOffset,int zOffset,scalar_t *lod,scalar_t *hid,int filterLen); static __global__ void cu_iwt3df_row(_data_t *out,_data_t *Ly,_data_t *Hy,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,int xOffset,int yOffset,int zOffset,scalar_t *lod,scalar_t *hid,int filterLen); static __global__ void cu_iwt3df_col(_data_t *out,_data_t *Lx,_data_t *Hx,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,int xOffset,int yOffset,int zOffset,scalar_t *lod,scalar_t *hid,int filterLen); static __global__ void cu_fwt3df_LC1(_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dxNext, int dyNext, int dzNext); static __global__ void cu_fwt3df_LC2(_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dxNext, int dyNext, int dzNext); static __global__ void cu_fwt3df_LC1_diff(_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dxNext, int dyNext, int dzNext); static __global__ void cu_fwt3df_LC2_diff(_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dxNext, int dyNext, int dzNext); static __global__ void cu_fwt3df_LC3(_data_t* HxHyHz_df1,_data_t* HxHyHz_df2,_data_t* HxHyHz_n,int dxNext, int dyNext, int dzNext); static __global__ void cu_iwt3df_LC1(_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dx, int dy, int dz); static __global__ void cu_iwt3df_LC2(_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dx, int dy, int dz); static __global__ void cu_iwt3df_LC1_diff(_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dx, int dy, int dz); static __global__ void cu_iwt3df_LC2_diff(_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dx, int dy, int dz); static __global__ void cu_iwt3df_LC3(_data_t* HxHyHz_df1,_data_t* HxHyHz_df2,_data_t* HxHyHz_n,int dx, int dy, int dz); static __global__ void cu_mult(_data_t* in, _data_t mult, int maxInd); static __global__ void cu_soft_thresh (_data_t* in, scalar_t thresh, int numMax); static __global__ void cu_circshift(_data_t* data, _data_t* dataCopy, int dx, int dy, int dz, int shift1, int shift2, int shift3); static __global__ void cu_circunshift(_data_t* data, _data_t* dataCopy, int dx, int dy, int dz, int shift1, int shift2, int shift3); extern "C" void dffwt3_gpuHost(struct dfwavelet_plan_s* plan, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn, data_t* in_vx,data_t* in_vy,data_t* in_vz) { assert(plan->use_gpu==2); data_t* dev_wcdf1,*dev_wcdf2,*dev_wcn,*dev_vx,*dev_vy,*dev_vz; cuda(Malloc( (void**)&dev_vx, plan->numPixel*sizeof(data_t) )); cuda(Malloc( (void**)&dev_vy, plan->numPixel*sizeof(data_t) )); cuda(Malloc( (void**)&dev_vz, plan->numPixel*sizeof(data_t) )); cuda(Memcpy( dev_vx, in_vx, plan->numPixel*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_vy, in_vy, plan->numPixel*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_vz, in_vz, plan->numPixel*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Malloc( (void**)&dev_wcdf1, plan->numCoeff*sizeof(data_t) )); cuda(Malloc( (void**)&dev_wcdf2, plan->numCoeff*sizeof(data_t) )); cuda(Malloc( (void**)&dev_wcn, plan->numCoeff*sizeof(data_t) )); dffwt3_gpu(plan,dev_wcdf1,dev_wcdf2,dev_wcn,dev_vx,dev_vy,dev_vz); cuda(Memcpy( out_wcdf1, dev_wcdf1, plan->numCoeff*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_wcdf2, dev_wcdf2, plan->numCoeff*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_wcn, dev_wcn, plan->numCoeff*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Free( dev_wcdf1 )); cuda(Free( dev_wcdf2 )); cuda(Free( dev_wcn )); cuda(Free( dev_vx )); cuda(Free( dev_vy )); cuda(Free( dev_vz )); } extern "C" void dfiwt3_gpuHost(struct dfwavelet_plan_s* plan, data_t* out_vx,data_t* out_vy,data_t* out_vz, data_t* in_wcdf1,data_t* in_wcdf2,data_t* in_wcn) { assert(plan->use_gpu==2); data_t* dev_wcdf1,*dev_wcdf2,*dev_wcn,*dev_vx,*dev_vy,*dev_vz; cuda(Malloc( (void**)&dev_wcdf1, plan->numCoeff*sizeof(data_t) )); cuda(Malloc( (void**)&dev_wcdf2, plan->numCoeff*sizeof(data_t) )); cuda(Malloc( (void**)&dev_wcn, plan->numCoeff*sizeof(data_t) )); cuda(Memcpy( dev_wcdf1, in_wcdf1, plan->numCoeff*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_wcdf2, in_wcdf2, plan->numCoeff*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_wcn, in_wcn, plan->numCoeff*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Malloc( (void**)&dev_vx, plan->numPixel*sizeof(data_t) )); cuda(Malloc( (void**)&dev_vy, plan->numPixel*sizeof(data_t) )); cuda(Malloc( (void**)&dev_vz, plan->numPixel*sizeof(data_t) )); dfiwt3_gpu(plan,dev_vx,dev_vy,dev_vz,dev_wcdf1,dev_wcdf2,dev_wcn); cuda(Memcpy( out_vx, dev_vx, plan->numPixel*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_vy, dev_vy, plan->numPixel*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_vz, dev_vz, plan->numPixel*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Free( dev_wcdf1 )); cuda(Free( dev_wcdf2 )); cuda(Free( dev_wcn )); cuda(Free( dev_vx )); cuda(Free( dev_vy )); cuda(Free( dev_vz )); } extern "C" void dfsoftthresh_gpuHost(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn) { assert(plan->use_gpu==2); data_t* dev_wcdf1,*dev_wcdf2,*dev_wcn; cuda(Malloc( (void**)&dev_wcdf1, plan->numCoeff*sizeof(data_t) )); cuda(Malloc( (void**)&dev_wcdf2, plan->numCoeff*sizeof(data_t) )); cuda(Malloc( (void**)&dev_wcn, plan->numCoeff*sizeof(data_t) )); cuda(Memcpy( dev_wcdf1, out_wcdf1, plan->numCoeff*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_wcdf2, out_wcdf2, plan->numCoeff*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_wcn, out_wcn, plan->numCoeff*sizeof(data_t), cudaMemcpyHostToDevice )); dfsoftthresh_gpu(plan,dfthresh,nthresh,dev_wcdf1,dev_wcdf2,dev_wcn); cuda(Memcpy( out_wcdf1, dev_wcdf1, plan->numCoeff*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_wcdf2, dev_wcdf2, plan->numCoeff*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_wcn, dev_wcn, plan->numCoeff*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Free( dev_wcdf1 )); cuda(Free( dev_wcdf2 )); cuda(Free( dev_wcn )); } extern "C" void dfwavthresh3_gpuHost(struct dfwavelet_plan_s* plan, scalar_t dfthresh,scalar_t nthresh,data_t* out_vx,data_t* out_vy,data_t* out_vz, data_t* in_vx,data_t* in_vy,data_t* in_vz) { assert(plan->use_gpu==2); data_t*dev_vx,*dev_vy,*dev_vz; cuda(Malloc( (void**)&dev_vx, plan->numPixel*sizeof(data_t) )); cuda(Malloc( (void**)&dev_vy, plan->numPixel*sizeof(data_t) )); cuda(Malloc( (void**)&dev_vz, plan->numPixel*sizeof(data_t) )); cuda(Memcpy( dev_vx, in_vx, plan->numPixel*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_vy, in_vy, plan->numPixel*sizeof(data_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_vz, in_vz, plan->numPixel*sizeof(data_t), cudaMemcpyHostToDevice )); dfwavthresh3_gpu(plan,dfthresh,nthresh,dev_vx,dev_vy,dev_vz,dev_vx,dev_vy,dev_vz); cuda(Memcpy( out_vx, dev_vx, plan->numPixel*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_vy, dev_vy, plan->numPixel*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Memcpy( out_vz, dev_vz, plan->numPixel*sizeof(data_t), cudaMemcpyDeviceToHost )); cuda(Free( dev_vx )); cuda(Free( dev_vy )); cuda(Free( dev_vz )); } extern "C" void dffwt3_gpu(struct dfwavelet_plan_s* plan, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn, data_t* in_vx,data_t* in_vy,data_t* in_vz) { circshift_gpu(plan,in_vx); circshift_gpu(plan,in_vy); circshift_gpu(plan,in_vz); long numCoeff, filterLen,*waveSizes; numCoeff = plan->numCoeff; waveSizes = plan->waveSizes; filterLen = plan->filterLen; int numLevels = plan->numLevels; // Cast from generic data_t to device compatible _data_t _data_t* dev_wcdf1 = (_data_t*) out_wcdf1; _data_t* dev_wcdf2 = (_data_t*) out_wcdf2; _data_t* dev_wcn = (_data_t*) out_wcn; _data_t* dev_in_vx = (_data_t*) in_vx; _data_t* dev_in_vy = (_data_t*) in_vy; _data_t* dev_in_vz = (_data_t*) in_vz; _data_t* res = (_data_t*) plan->res; _data_t* dev_temp1,*dev_temp2; cuda(Malloc( (void**)&dev_temp1, numCoeff*sizeof(_data_t) )); cuda(Malloc( (void**)&dev_temp2, numCoeff*sizeof(_data_t) )); // Get dimensions int dx = plan->imSize[0]; int dy = plan->imSize[1]; int dz = plan->imSize[2]; int dxNext = waveSizes[0 + 3*numLevels]; int dyNext = waveSizes[1 + 3*numLevels]; int dzNext = waveSizes[2 + 3*numLevels]; int blockSize = dxNext*dyNext*dzNext; // allocate device memory and copy filters to device scalar_t *dev_filters; cuda(Malloc( (void**)&dev_filters, 4*plan->filterLen*sizeof(scalar_t) )); scalar_t *dev_lod0 = dev_filters + 0*plan->filterLen; scalar_t *dev_hid0 = dev_filters + 1*plan->filterLen; scalar_t *dev_lod1 = dev_filters + 2*plan->filterLen; scalar_t *dev_hid1 = dev_filters + 3*plan->filterLen; cuda(Memcpy( dev_lod0, plan->lod0, 2*plan->filterLen*sizeof(scalar_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_lod1, plan->lod1, 2*plan->filterLen*sizeof(scalar_t), cudaMemcpyHostToDevice )); // Initialize variables and Pointers for FWT int const SHMEM_SIZE = 16384; int const T = 512; int mem, K; dim3 numBlocks, numThreads; // Temp Pointers _data_t *dev_tempLx,*dev_tempHx; dev_tempLx = dev_temp1; dev_tempHx = dev_tempLx + numCoeff/2; _data_t *dev_tempLxLy,*dev_tempHxLy,*dev_tempLxHy,*dev_tempHxHy; dev_tempLxLy = dev_temp2; dev_tempHxLy = dev_tempLxLy + numCoeff/4; dev_tempLxHy = dev_tempHxLy + numCoeff/4; dev_tempHxHy = dev_tempLxHy + numCoeff/4; // wcdf1 Pointers _data_t *dev_LxLyLz_df1,*dev_HxLyLz_df1,*dev_LxHyLz_df1,*dev_HxHyLz_df1,*dev_LxLyHz_df1,*dev_HxLyHz_df1,*dev_LxHyHz_df1,*dev_HxHyHz_df1,*dev_current_vx; dev_LxLyLz_df1 = dev_wcdf1; dev_HxLyLz_df1 = dev_LxLyLz_df1 + waveSizes[0]*waveSizes[1]*waveSizes[2]; for (int l = 1; l <= numLevels; ++l){ dev_HxLyLz_df1 += 7*waveSizes[0 + 3*l]*waveSizes[1 + 3*l]*waveSizes[2 + 3*l]; } dev_current_vx = dev_in_vx; // wcdf2 Pointers _data_t *dev_LxLyLz_df2,*dev_HxLyLz_df2,*dev_LxHyLz_df2,*dev_HxHyLz_df2,*dev_LxLyHz_df2,*dev_HxLyHz_df2,*dev_LxHyHz_df2,*dev_HxHyHz_df2,*dev_current_vy; dev_LxLyLz_df2 = dev_wcdf2; dev_HxLyLz_df2 = dev_LxLyLz_df2 + waveSizes[0]*waveSizes[1]*waveSizes[2]; for (int l = 1; l <= numLevels; ++l){ dev_HxLyLz_df2 += 7*waveSizes[0 + 3*l]*waveSizes[1 + 3*l]*waveSizes[2 + 3*l]; } dev_current_vy = dev_in_vy; // wcn Pointers _data_t *dev_LxLyLz_n,*dev_HxLyLz_n,*dev_LxHyLz_n,*dev_HxHyLz_n,*dev_LxLyHz_n,*dev_HxLyHz_n,*dev_LxHyHz_n,*dev_HxHyHz_n,*dev_current_vz; dev_LxLyLz_n = dev_wcn; dev_HxLyLz_n = dev_LxLyLz_n + waveSizes[0]*waveSizes[1]*waveSizes[2]; for (int l = 1; l <= numLevels; ++l){ dev_HxLyLz_n += 7*waveSizes[0 + 3*l]*waveSizes[1 + 3*l]*waveSizes[2 + 3*l]; } dev_current_vz = dev_in_vz; //*****************Loop through levels**************** for (int l = numLevels; l >= 1; --l) { dxNext = waveSizes[0 + 3*l]; dyNext = waveSizes[1 + 3*l]; dzNext = waveSizes[2 + 3*l]; blockSize = dxNext*dyNext*dzNext; // Update Pointers // df1 dev_HxLyLz_df1 = dev_HxLyLz_df1 - 7*blockSize; dev_LxHyLz_df1 = dev_HxLyLz_df1 + blockSize; dev_HxHyLz_df1 = dev_LxHyLz_df1 + blockSize; dev_LxLyHz_df1 = dev_HxHyLz_df1 + blockSize; dev_HxLyHz_df1 = dev_LxLyHz_df1 + blockSize; dev_LxHyHz_df1 = dev_HxLyHz_df1 + blockSize; dev_HxHyHz_df1 = dev_LxHyHz_df1 + blockSize; // df2 dev_HxLyLz_df2 = dev_HxLyLz_df2 - 7*blockSize; dev_LxHyLz_df2 = dev_HxLyLz_df2 + blockSize; dev_HxHyLz_df2 = dev_LxHyLz_df2 + blockSize; dev_LxLyHz_df2 = dev_HxHyLz_df2 + blockSize; dev_HxLyHz_df2 = dev_LxLyHz_df2 + blockSize; dev_LxHyHz_df2 = dev_HxLyHz_df2 + blockSize; dev_HxHyHz_df2 = dev_LxHyHz_df2 + blockSize; // n dev_HxLyLz_n = dev_HxLyLz_n - 7*blockSize; dev_LxHyLz_n = dev_HxLyLz_n + blockSize; dev_HxHyLz_n = dev_LxHyLz_n + blockSize; dev_LxLyHz_n = dev_HxHyLz_n + blockSize; dev_HxLyHz_n = dev_LxLyHz_n + blockSize; dev_LxHyHz_n = dev_HxLyHz_n + blockSize; dev_HxHyHz_n = dev_LxHyHz_n + blockSize; //************WCVX*********** // FWT Columns K = (SHMEM_SIZE-16)/(dx*sizeof(_data_t)); numBlocks = dim3(1,(dy+K-1)/K,dz); numThreads = dim3(T/K,K,1); mem = K*dx*sizeof(_data_t); cu_fwt3df_col <<< numBlocks,numThreads,mem >>>(dev_tempLx,dev_tempHx,dev_current_vx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cuda_sync(); // FWT Rows K = (SHMEM_SIZE-16)/(dy*sizeof(_data_t)); numBlocks = dim3(((dxNext)+K-1)/K,1,dz); numThreads = dim3(K,T/K,1); mem = K*dy*sizeof(_data_t); cu_fwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempLxLy,dev_tempLxHy,dev_tempLx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempHxLy,dev_tempHxHy,dev_tempHx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cuda_sync(); // FWT Depths K = (SHMEM_SIZE-16)/(dz*sizeof(_data_t)); numBlocks = dim3(((dxNext)+K-1)/K,dyNext,1); numThreads = dim3(K,1,T/K); mem = K*dz*sizeof(_data_t); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_LxLyLz_df1,dev_LxLyHz_df1,dev_tempLxLy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_LxHyLz_df1,dev_LxHyHz_df1,dev_tempLxHy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_HxLyLz_df1,dev_HxLyHz_df1,dev_tempHxLy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_HxHyLz_df1,dev_HxHyHz_df1,dev_tempHxHy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cuda_sync(); //************WCVY*********** // FWT Columns K = (SHMEM_SIZE-16)/(dx*sizeof(_data_t)); numBlocks = dim3(1,(dy+K-1)/K,dz); numThreads = dim3(T/K,K,1); mem = K*dx*sizeof(_data_t); cu_fwt3df_col <<< numBlocks,numThreads,mem >>>(dev_tempLx,dev_tempHx,dev_current_vy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cuda_sync(); // FWT Rows K = (SHMEM_SIZE-16)/(dy*sizeof(_data_t)); numBlocks = dim3(((dxNext)+K-1)/K,1,dz); numThreads = dim3(K,T/K,1); mem = K*dy*sizeof(_data_t); cu_fwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempLxLy,dev_tempLxHy,dev_tempLx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cu_fwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempHxLy,dev_tempHxHy,dev_tempHx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cuda_sync(); // FWT Depths K = (SHMEM_SIZE-16)/(dz*sizeof(_data_t)); numBlocks = dim3(((dxNext)+K-1)/K,dyNext,1); numThreads = dim3(K,1,T/K); mem = K*dz*sizeof(_data_t); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_LxLyLz_df2,dev_LxLyHz_df2,dev_tempLxLy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_LxHyLz_df2,dev_LxHyHz_df2,dev_tempLxHy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_HxLyLz_df2,dev_HxLyHz_df2,dev_tempHxLy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_HxHyLz_df2,dev_HxHyHz_df2,dev_tempHxHy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cuda_sync(); //************WCVZ*********** // FWT Columns K = (SHMEM_SIZE-16)/(dx*sizeof(_data_t)); numBlocks = dim3(1,(dy+K-1)/K,dz); numThreads = dim3(T/K,K,1); mem = K*dx*sizeof(_data_t); cu_fwt3df_col <<< numBlocks,numThreads,mem >>>(dev_tempLx,dev_tempHx,dev_current_vz,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cuda_sync(); // FWT Rows K = (SHMEM_SIZE-16)/(dy*sizeof(_data_t)); numBlocks = dim3(((dxNext)+K-1)/K,1,dz); numThreads = dim3(K,T/K,1); mem = K*dy*sizeof(_data_t); cu_fwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempLxLy,dev_tempLxHy,dev_tempLx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cu_fwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempHxLy,dev_tempHxHy,dev_tempHx,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod0,dev_hid0,filterLen); cuda_sync(); // FWT Depths K = (SHMEM_SIZE-16)/(dz*sizeof(_data_t)); numBlocks = dim3(((dxNext)+K-1)/K,dyNext,1); numThreads = dim3(K,1,T/K); mem = K*dz*sizeof(_data_t); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_LxLyLz_n,dev_LxLyHz_n,dev_tempLxLy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_LxHyLz_n,dev_LxHyHz_n,dev_tempLxHy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_HxLyLz_n,dev_HxLyHz_n,dev_tempHxLy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cu_fwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_HxHyLz_n,dev_HxHyHz_n,dev_tempHxHy,dx,dy,dz,dxNext,dyNext,dzNext,dev_lod1,dev_hid1,filterLen); cuda_sync(); //******* Multi ****** int maxInd = 7*blockSize; numThreads = T; numBlocks = (maxInd+numThreads.x-1)/numThreads.x; cu_mult <<< numBlocks, numThreads >>> (dev_HxLyLz_df1,1.f/res[0],maxInd); cu_mult <<< numBlocks, numThreads >>> (dev_HxLyLz_df2,1.f/res[1],maxInd); cu_mult <<< numBlocks, numThreads >>> (dev_HxLyLz_n,1.f/res[2],maxInd); cuda_sync(); //*******Linear Combination****** int t1 = min(dxNext,T); int t2 = T/t1; numBlocks = dim3( (dxNext+t1-1)/t1, (dyNext+t2-1)/t2, dzNext); numThreads = dim3(t1,t2,1); cu_fwt3df_LC1 <<< numBlocks,numThreads >>> (dev_HxLyLz_df1,dev_HxLyLz_df2,dev_HxLyLz_n,dev_LxHyLz_df1,dev_LxHyLz_df2,dev_LxHyLz_n,dev_LxLyHz_df1,dev_LxLyHz_df2,dev_LxLyHz_n,dxNext,dyNext,dzNext); cu_fwt3df_LC2 <<< numBlocks,numThreads >>> (dev_HxHyLz_df1,dev_HxHyLz_df2,dev_HxHyLz_n,dev_HxLyHz_df1,dev_HxLyHz_df2,dev_HxLyHz_n,dev_LxHyHz_df1,dev_LxHyHz_df2,dev_LxHyHz_n,dxNext,dyNext,dzNext); cu_fwt3df_LC3 <<< numBlocks,numThreads >>> (dev_HxHyHz_df1,dev_HxHyHz_df2,dev_HxHyHz_n,dxNext,dyNext,dzNext); cuda_sync(); cu_fwt3df_LC1_diff <<< numBlocks,numThreads >>> (dev_HxLyLz_df1,dev_HxLyLz_df2,dev_HxLyLz_n,dev_LxHyLz_df1,dev_LxHyLz_df2,dev_LxHyLz_n,dev_LxLyHz_df1,dev_LxLyHz_df2,dev_LxLyHz_n,dxNext,dyNext,dzNext); cu_fwt3df_LC2_diff <<< numBlocks,numThreads >>> (dev_HxHyLz_df1,dev_HxHyLz_df2,dev_HxHyLz_n,dev_HxLyHz_df1,dev_HxLyHz_df2,dev_HxLyHz_n,dev_LxHyHz_df1,dev_LxHyHz_df2,dev_LxHyHz_n,dxNext,dyNext,dzNext); cuda_sync(); dev_current_vx = dev_wcdf1; dev_current_vy = dev_wcdf2; dev_current_vz = dev_wcn; dx = dxNext; dy = dyNext; dz = dzNext; } cuda(Free( dev_filters )); cuda(Free( dev_temp1 )); cuda(Free( dev_temp2 )); circunshift_gpu(plan,in_vx); circunshift_gpu(plan,in_vy); circunshift_gpu(plan,in_vz); } extern "C" void dfiwt3_gpu(struct dfwavelet_plan_s* plan, data_t* out_vx,data_t* out_vy,data_t* out_vz, data_t* in_wcdf1,data_t* in_wcdf2,data_t* in_wcn) { long numCoeff, filterLen,*waveSizes; numCoeff = plan->numCoeff; waveSizes = plan->waveSizes; filterLen = plan->filterLen; int numLevels = plan->numLevels; // Cast from generic data_t to device compatible _data_t _data_t* dev_out_vx = (_data_t*)out_vx; _data_t* dev_out_vy = (_data_t*)out_vy; _data_t* dev_out_vz = (_data_t*)out_vz; _data_t* dev_wcdf1 = (_data_t*)in_wcdf1; _data_t* dev_wcdf2 = (_data_t*)in_wcdf2; _data_t* dev_wcn = (_data_t*)in_wcn; _data_t* res = (_data_t*) plan->res; _data_t* dev_temp1, *dev_temp2; cuda(Malloc( (void**)&dev_temp1, numCoeff*sizeof(_data_t) )); cuda(Malloc( (void**)&dev_temp2, numCoeff*sizeof(_data_t)) ); // allocate device memory scalar_t *dev_filters; cuda(Malloc( (void**)&dev_filters, 4*(plan->filterLen)*sizeof(scalar_t) )); scalar_t *dev_lor0 = dev_filters + 0*plan->filterLen; scalar_t *dev_hir0 = dev_filters + 1*plan->filterLen; scalar_t *dev_lor1 = dev_filters + 2*plan->filterLen; scalar_t *dev_hir1 = dev_filters + 3*plan->filterLen; cuda(Memcpy( dev_lor0, plan->lor0, 2*plan->filterLen*sizeof(scalar_t), cudaMemcpyHostToDevice )); cuda(Memcpy( dev_lor1, plan->lor1, 2*plan->filterLen*sizeof(scalar_t), cudaMemcpyHostToDevice )); // Workspace dimensions int dxWork = waveSizes[0 + 3*numLevels]*2-1 + filterLen-1; int dyWork = waveSizes[1 + 3*numLevels]*2-1 + filterLen-1; int dzWork = waveSizes[2 + 3*numLevels]*2-1 + filterLen-1; // Initialize variables and pointers for IWT int const SHMEM_SIZE = 16384; int const T = 512; int mem,K; dim3 numBlocks, numThreads; int dx = waveSizes[0]; int dy = waveSizes[1]; int dz = waveSizes[2]; // Temp Pointers _data_t *dev_tempLxLy,*dev_tempHxLy,*dev_tempLxHy,*dev_tempHxHy; dev_tempLxLy = dev_temp1; dev_tempHxLy = dev_tempLxLy + numCoeff/4; dev_tempLxHy = dev_tempHxLy + numCoeff/4; dev_tempHxHy = dev_tempLxHy + numCoeff/4; _data_t *dev_tempLx,*dev_tempHx; dev_tempLx = dev_temp2; dev_tempHx = dev_tempLx + numCoeff/2; // wcdf1 Pointers _data_t *dev_LxLyLz_df1,*dev_HxLyLz_df1,*dev_LxHyLz_df1,*dev_HxHyLz_df1,*dev_LxLyHz_df1,*dev_HxLyHz_df1,*dev_LxHyHz_df1,*dev_HxHyHz_df1,*dev_current_vx; dev_LxLyLz_df1 = dev_wcdf1; dev_HxLyLz_df1 = dev_LxLyLz_df1 + dx*dy*dz; dev_current_vx = dev_LxLyLz_df1; // wcdf2 Pointers _data_t *dev_LxLyLz_df2,*dev_HxLyLz_df2,*dev_LxHyLz_df2,*dev_HxHyLz_df2,*dev_LxLyHz_df2,*dev_HxLyHz_df2,*dev_LxHyHz_df2,*dev_HxHyHz_df2,*dev_current_vy; dev_LxLyLz_df2 = dev_wcdf2; dev_HxLyLz_df2 = dev_LxLyLz_df2 + dx*dy*dz; dev_current_vy = dev_LxLyLz_df2; // wcn Pointers _data_t *dev_LxLyLz_n,*dev_HxLyLz_n,*dev_LxHyLz_n,*dev_HxHyLz_n,*dev_LxLyHz_n,*dev_HxLyHz_n,*dev_LxHyHz_n,*dev_HxHyHz_n,*dev_current_vz; dev_LxLyLz_n = dev_wcn; dev_HxLyLz_n = dev_LxLyLz_n + dx*dy*dz; dev_current_vz = dev_LxLyLz_n; for (int level = 1; level < numLevels+1; ++level) { dx = waveSizes[0 + 3*level]; dy = waveSizes[1 + 3*level]; dz = waveSizes[2 + 3*level]; int blockSize = dx*dy*dz; int dxNext = waveSizes[0+3*(level+1)]; int dyNext = waveSizes[1+3*(level+1)]; int dzNext = waveSizes[2+3*(level+1)]; // Calclate Offset dxWork = (2*dx-1 + filterLen-1); dyWork = (2*dy-1 + filterLen-1); dzWork = (2*dz-1 + filterLen-1); int xOffset = (int) floor((dxWork - dxNext) / 2.0); int yOffset = (int) floor((dyWork - dyNext) / 2.0); int zOffset = (int) floor((dzWork - dzNext) / 2.0); // Update Pointers // df1 dev_LxHyLz_df1 = dev_HxLyLz_df1 + blockSize; dev_HxHyLz_df1 = dev_LxHyLz_df1 + blockSize; dev_LxLyHz_df1 = dev_HxHyLz_df1 + blockSize; dev_HxLyHz_df1 = dev_LxLyHz_df1 + blockSize; dev_LxHyHz_df1 = dev_HxLyHz_df1 + blockSize; dev_HxHyHz_df1 = dev_LxHyHz_df1 + blockSize; // df2 dev_LxHyLz_df2 = dev_HxLyLz_df2 + blockSize; dev_HxHyLz_df2 = dev_LxHyLz_df2 + blockSize; dev_LxLyHz_df2 = dev_HxHyLz_df2 + blockSize; dev_HxLyHz_df2 = dev_LxLyHz_df2 + blockSize; dev_LxHyHz_df2 = dev_HxLyHz_df2 + blockSize; dev_HxHyHz_df2 = dev_LxHyHz_df2 + blockSize; // n dev_LxHyLz_n = dev_HxLyLz_n + blockSize; dev_HxHyLz_n = dev_LxHyLz_n + blockSize; dev_LxLyHz_n = dev_HxHyLz_n + blockSize; dev_HxLyHz_n = dev_LxLyHz_n + blockSize; dev_LxHyHz_n = dev_HxLyHz_n + blockSize; dev_HxHyHz_n = dev_LxHyHz_n + blockSize; //*******Linear Combination****** int t1 = min(dxNext,T); int t2 = T/t1; numBlocks = dim3( (dx+t1-1)/t1, (dy+t2-1)/t2, dz); numThreads = dim3(t1,t2,1); cu_iwt3df_LC1 <<< numBlocks,numThreads >>> (dev_HxLyLz_df1,dev_HxLyLz_df2,dev_HxLyLz_n,dev_LxHyLz_df1,dev_LxHyLz_df2,dev_LxHyLz_n,dev_LxLyHz_df1,dev_LxLyHz_df2,dev_LxLyHz_n,dx,dy,dz); cu_iwt3df_LC2 <<< numBlocks,numThreads >>> (dev_HxHyLz_df1,dev_HxHyLz_df2,dev_HxHyLz_n,dev_HxLyHz_df1,dev_HxLyHz_df2,dev_HxLyHz_n,dev_LxHyHz_df1,dev_LxHyHz_df2,dev_LxHyHz_n,dx,dy,dz); cu_iwt3df_LC3 <<< numBlocks,numThreads >>> (dev_HxHyHz_df1,dev_HxHyHz_df2,dev_HxHyHz_n,dx,dy,dz); cuda_sync(); cu_iwt3df_LC1_diff <<< numBlocks,numThreads >>> (dev_HxLyLz_df1,dev_HxLyLz_df2,dev_HxLyLz_n,dev_LxHyLz_df1,dev_LxHyLz_df2,dev_LxHyLz_n,dev_LxLyHz_df1,dev_LxLyHz_df2,dev_LxLyHz_n,dx,dy,dz); cu_iwt3df_LC2_diff <<< numBlocks,numThreads >>> (dev_HxHyLz_df1,dev_HxHyLz_df2,dev_HxHyLz_n,dev_HxLyHz_df1,dev_HxLyHz_df2,dev_HxLyHz_n,dev_LxHyHz_df1,dev_LxHyHz_df2,dev_LxHyHz_n,dx,dy,dz); cuda_sync(); //******* Multi ****** int maxInd = 7*blockSize; numThreads = T; numBlocks = (maxInd+numThreads.x-1)/numThreads.x; cu_mult <<< numBlocks, numThreads >>> (dev_HxLyLz_df1,res[0],maxInd); cu_mult <<< numBlocks, numThreads >>> (dev_HxLyLz_df2,res[1],maxInd); cu_mult <<< numBlocks, numThreads >>> (dev_HxLyLz_n,res[2],maxInd); cuda_sync(); //************WCX************ // Update Pointers if (level==numLevels) dev_current_vx = dev_out_vx; // IWT Depths K = (SHMEM_SIZE-16)/(2*dz*sizeof(_data_t)); numBlocks = dim3((dx+K-1)/K,dy,1); numThreads = dim3(K,1,(T/K)); mem = K*2*dz*sizeof(_data_t); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempLxLy,dev_LxLyLz_df1,dev_LxLyHz_df1,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempHxLy,dev_HxLyLz_df1,dev_HxLyHz_df1,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempLxHy,dev_LxHyLz_df1,dev_LxHyHz_df1,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempHxHy,dev_HxHyLz_df1,dev_HxHyHz_df1,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cuda_sync(); // IWT Rows K = (SHMEM_SIZE-16)/(2*dy*sizeof(_data_t)); numBlocks = dim3((dx+K-1)/K,1,dzNext); numThreads = dim3(K,(T/K),1); mem = K*2*dy*sizeof(_data_t); cu_iwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempLx,dev_tempLxLy,dev_tempLxHy,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,plan->filterLen); cu_iwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempHx,dev_tempHxLy,dev_tempHxHy,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,plan->filterLen); cuda_sync(); // IWT Columns K = (SHMEM_SIZE-16)/(2*dx*sizeof(_data_t)); numBlocks = dim3(1,(dyNext+K-1)/K,dzNext); numThreads = dim3((T/K),K,1); mem = K*2*dx*sizeof(_data_t); cu_iwt3df_col <<< numBlocks,numThreads,mem >>>(dev_current_vx,dev_tempLx,dev_tempHx,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,plan->filterLen); cuda_sync(); //************WCY************ // Update Pointers if (level==numLevels) dev_current_vy = dev_out_vy; // IWT Depths K = (SHMEM_SIZE-16)/(2*dz*sizeof(_data_t)); numBlocks = dim3((dx+K-1)/K,dy,1); numThreads = dim3(K,1,(T/K)); mem = K*2*dz*sizeof(_data_t); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempLxLy,dev_LxLyLz_df2,dev_LxLyHz_df2,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempHxLy,dev_HxLyLz_df2,dev_HxLyHz_df2,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempLxHy,dev_LxHyLz_df2,dev_LxHyHz_df2,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempHxHy,dev_HxHyLz_df2,dev_HxHyHz_df2,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,filterLen); cuda_sync(); // IWT Rows K = (SHMEM_SIZE-16)/(2*dy*sizeof(_data_t)); numBlocks = dim3((dx+K-1)/K,1,dzNext); numThreads = dim3(K,(T/K),1); mem = K*2*dy*sizeof(_data_t); cu_iwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempLx,dev_tempLxLy,dev_tempLxHy,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,plan->filterLen); cu_iwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempHx,dev_tempHxLy,dev_tempHxHy,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,plan->filterLen); cuda_sync(); // IWT Columns K = (SHMEM_SIZE-16)/(2*dx*sizeof(_data_t)); numBlocks = dim3(1,(dyNext+K-1)/K,dzNext); numThreads = dim3((T/K),K,1); mem = K*2*dx*sizeof(_data_t); cu_iwt3df_col <<< numBlocks,numThreads,mem >>>(dev_current_vy,dev_tempLx,dev_tempHx,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,plan->filterLen); cuda_sync(); //************WCZ************ // Update Pointers if (level==numLevels) dev_current_vz = dev_out_vz; // IWT Depths K = (SHMEM_SIZE-16)/(2*dz*sizeof(_data_t)); numBlocks = dim3((dx+K-1)/K,dy,1); numThreads = dim3(K,1,(T/K)); mem = K*2*dz*sizeof(_data_t); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempLxLy,dev_LxLyLz_n,dev_LxLyHz_n,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempHxLy,dev_HxLyLz_n,dev_HxLyHz_n,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempLxHy,dev_LxHyLz_n,dev_LxHyHz_n,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,filterLen); cu_iwt3df_dep <<< numBlocks,numThreads,mem >>>(dev_tempHxHy,dev_HxHyLz_n,dev_HxHyHz_n,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor1,dev_hir1,filterLen); cuda_sync(); // IWT Rows K = (SHMEM_SIZE-16)/(2*dy*sizeof(_data_t)); numBlocks = dim3((dx+K-1)/K,1,dzNext); numThreads = dim3(K,(T/K),1); mem = K*2*dy*sizeof(_data_t); cu_iwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempLx,dev_tempLxLy,dev_tempLxHy,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,plan->filterLen); cu_iwt3df_row <<< numBlocks,numThreads,mem >>>(dev_tempHx,dev_tempHxLy,dev_tempHxHy,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,plan->filterLen); cuda_sync(); // IWT Columns K = (SHMEM_SIZE-16)/(2*dx*sizeof(_data_t)); numBlocks = dim3(1,(dyNext+K-1)/K,dzNext); numThreads = dim3((T/K),K,1); mem = K*2*dx*sizeof(_data_t); cu_iwt3df_col <<< numBlocks,numThreads,mem >>>(dev_current_vz,dev_tempLx,dev_tempHx,dx,dy,dz,dxNext,dyNext,dzNext,xOffset,yOffset,zOffset,dev_lor0,dev_hir0,plan->filterLen); cuda_sync(); dev_HxLyLz_df1 += 7*blockSize; dev_HxLyLz_df2 += 7*blockSize; dev_HxLyLz_n += 7*blockSize; } cuda(Free( dev_filters )); cuda(Free( dev_temp1 )); cuda(Free( dev_temp2 )); circunshift_gpu(plan,out_vx); circunshift_gpu(plan,out_vy); circunshift_gpu(plan,out_vz); } int rand_lim(int limit) { int divisor = RAND_MAX/(limit+1); int retval; do { retval = rand() / divisor; } while (retval > limit); return retval; } void dfwavelet_new_randshift_gpu (struct dfwavelet_plan_s* plan) { int i; i = rand(); for(i = 0; i < plan->numdims; i++) { // Determine maximum shift value for this dimension int log2dim = 1; while( (1<imSize[i]) { log2dim++; } int maxShift = 1 << (log2dim-plan->numLevels); if (maxShift > 8) { maxShift = 8; } // Generate random shift value between 0 and maxShift plan->randShift[i] = rand_lim(maxShift); } } extern "C" void dfwavthresh3_gpu(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh,data_t* out_vx,data_t* out_vy,data_t* out_vz,data_t* in_vx,data_t* in_vy,data_t* in_vz) { data_t* dev_wcdf1,*dev_wcdf2,*dev_wcn; cuda(Malloc( (void**)&dev_wcdf1, plan->numCoeff*sizeof(_data_t) )); cuda(Malloc( (void**)&dev_wcdf2, plan->numCoeff*sizeof(_data_t) )); cuda(Malloc( (void**)&dev_wcn, plan->numCoeff*sizeof(_data_t) )); dffwt3_gpu(plan,dev_wcdf1,dev_wcdf2,dev_wcn,in_vx,in_vy,in_vz); dfsoftthresh_gpu(plan,dfthresh,nthresh,dev_wcdf1,dev_wcdf2,dev_wcn); dfiwt3_gpu(plan,out_vx,out_vy,out_vz,dev_wcdf1,dev_wcdf2,dev_wcn); cuda(Free( dev_wcdf1 )); cuda(Free( dev_wcdf2 )); cuda(Free( dev_wcn )); } extern "C" void dfsoftthresh_gpu(struct dfwavelet_plan_s* plan,scalar_t dfthresh, scalar_t nthresh, data_t* out_wcdf1,data_t* out_wcdf2,data_t* out_wcn) { assert(plan->use_gpu==1||plan->use_gpu==2); _data_t* dev_wcdf1,*dev_wcdf2,*dev_wcn; dev_wcdf1 = (_data_t*) out_wcdf1; dev_wcdf2 = (_data_t*) out_wcdf2; dev_wcn = (_data_t*) out_wcn; int numMax; int const T = 512; dim3 numBlocks, numThreads; numMax = plan->numCoeff-plan->numCoarse; numBlocks = dim3((numMax+T-1)/T,1,1); numThreads = dim3(T,1,1); cu_soft_thresh <<< numBlocks,numThreads>>> (dev_wcdf1+plan->numCoarse,dfthresh,numMax); cu_soft_thresh <<< numBlocks,numThreads>>> (dev_wcdf2+plan->numCoarse,dfthresh,numMax); cu_soft_thresh <<< numBlocks,numThreads>>> (dev_wcn+plan->numCoarse,nthresh,numMax); } /********** Aux functions **********/ extern "C" void circshift_gpu(struct dfwavelet_plan_s* plan, data_t* data_c) { // Return if no shifts int zeroShift = 1; int i; for (i = 0; i< plan->numdims; i++) { zeroShift &= (plan->randShift[i]==0); } if(zeroShift) { return; } _data_t* data = (_data_t*) data_c; // Copy data _data_t* dataCopy; cuda(Malloc((void**)&dataCopy, plan->numPixel*sizeof(_data_t))); cuda(Memcpy(dataCopy, data, plan->numPixel*sizeof(_data_t), cudaMemcpyDeviceToDevice)); int T = 512; if (plan->numdims==2) { int dx,dy,r0,r1; dx = plan->imSize[0]; dy = plan->imSize[1]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; cu_circshift <<< (plan->numPixel+T-1)/T, T>>>(data,dataCopy,dx,dy,1,r0,r1,0); } else if (plan->numdims==3) { int dx,dy,dz,r0,r1,r2; dx = plan->imSize[0]; dy = plan->imSize[1]; dz = plan->imSize[2]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; r2 = plan->randShift[2]; cu_circshift <<< (plan->numPixel+T-1)/T, T>>>(data,dataCopy,dx,dy,dz,r0,r1,r2); } cuda(Free(dataCopy)); } extern "C" void circunshift_gpu(struct dfwavelet_plan_s* plan, data_t* data_c) { // Return if no shifts int zeroShift = 1; int i; for (i = 0; i< plan->numdims; i++) { zeroShift &= (plan->randShift[i]==0); } if(zeroShift) { return; } _data_t* data = (_data_t*) data_c; // Copy data _data_t* dataCopy; cuda(Malloc((void**)&dataCopy, plan->numPixel*sizeof(_data_t))); cuda(Memcpy(dataCopy, data, plan->numPixel*sizeof(_data_t), cudaMemcpyDeviceToDevice)); int T = 512; if (plan->numdims==2) { int dx,dy,r0,r1; dx = plan->imSize[0]; dy = plan->imSize[1]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; cu_circunshift <<< (plan->numPixel+T-1)/T, T>>>(data,dataCopy,dx,dy,1,r0,r1,0); } else if (plan->numdims==3) { int dx,dy,dz,r0,r1,r2; dx = plan->imSize[0]; dy = plan->imSize[1]; dz = plan->imSize[2]; r0 = plan->randShift[0]; r1 = plan->randShift[1]; r2 = plan->randShift[2]; cu_circunshift <<< (plan->numPixel+T-1)/T, T>>>(data,dataCopy,dx,dy,dz,r0,r1,r2); } cuda(Free(dataCopy)); } // ############################################################################ // CUDA function of fwt column convolution // Loads data to scratchpad (shared memory) and convolve w/ low pass and high pass // Output: Lx, Hx // Input: in, dx, dy, dz, dxNext, lod, hid, filterLen // ############################################################################ extern "C" __global__ void cu_fwt3df_col(_data_t *Lx,_data_t *Hx,_data_t *in,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,scalar_t *lod,scalar_t *hid,int filterLen) { extern __shared__ _data_t cols []; int ti = threadIdx.x; int tj = threadIdx.y; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; if (j>=dy) { return; } // Load Input to Temp Array for (int i = ti; i < dx; i += blockDim.x){ cols[i + tj*dx] = in[i + j*dx + k*dx*dy]; } __syncthreads(); // Low-Pass and High-Pass Downsample int ind, lessThan, greaThan; for (int i = ti; i < dxNext; i += blockDim.x){ _data_t y = cols[0]-cols[0]; _data_t z = cols[0]-cols[0]; #pragma unroll for (int f = 0; f < filterLen; f++){ ind = 2*i+1 - (filterLen-1)+f; lessThan = (int) (ind<0); greaThan = (int) (ind>=dx); ind = -1*lessThan+ind*(-2*lessThan+1); ind = (2*dx-1)*greaThan+ind*(-2*greaThan+1); y += cols[ind + tj*dx] * lod[filterLen-1-f]; z += cols[ind + tj*dx] * hid[filterLen-1-f]; } Lx[i + j*dxNext + k*dxNext*dy] = y; Hx[i + j*dxNext + k*dxNext*dy] = z; } } // ############################################################################ // CUDA function of fwt row convolution. Assumes fwt_col() has already been called // Loads data to scratchpad (shared memory) and convolve w/ low pass and high pass // Output: LxLy, LxHy / HxLy, HxHy // Input: Lx/Hx, dx, dy, dxNext, dyNext, lod, hid, filterLen // ############################################################################ extern "C" __global__ void cu_fwt3df_row(_data_t *Ly,_data_t *Hy,_data_t *in,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,scalar_t *lod,scalar_t *hid,int filterLen) { extern __shared__ _data_t rows []; int const K = blockDim.x; int ti = threadIdx.x; int tj = threadIdx.y; int i = blockIdx.x*blockDim.x+threadIdx.x; int k = blockIdx.z*blockDim.z+threadIdx.z; if (i>=dxNext) { return; } for (int j = tj; j < dy; j += blockDim.y){ rows[ti + j*K] = in[i + j*dxNext + k*dxNext*dy]; } __syncthreads(); // Low-Pass and High Pass Downsample int ind, lessThan, greaThan; for (int j = tj; j < dyNext; j += blockDim.y){ _data_t y = rows[0]-rows[0]; _data_t z = rows[0]-rows[0]; #pragma unroll for (int f = 0; f < filterLen; f++){ ind = 2*j+1 - (filterLen-1)+f; lessThan = (int) (ind<0); greaThan = (int) (ind>=dy); ind = -1*lessThan+ind*(-2*lessThan+1); ind = (2*dy-1)*greaThan+ind*(-2*greaThan+1); y += rows[ti + ind*K] * lod[filterLen-1-f]; z += rows[ti + ind*K] * hid[filterLen-1-f]; } Ly[i + j*dxNext + k*dxNext*dyNext] = y; Hy[i + j*dxNext + k*dxNext*dyNext] = z; } } // ############################################################################ // CUDA function of fwt depth convolution. Assumes fwt_row() has already been called // Loads data to scratchpad (shared memory) and convolve w/ low pass and high pass // Output: LxLy, LxHy / HxLy, HxHy // Input: Lx/Hx, dx, dy, dxNext, dyNext, lod, hid, filterLen // ############################################################################ extern "C" __global__ void cu_fwt3df_dep(_data_t *Lz,_data_t *Hz,_data_t *in,int dx,int dy,int dz,int dxNext,int dyNext,int dzNext,scalar_t *lod,scalar_t *hid,int filterLen) { extern __shared__ _data_t deps []; int const K = blockDim.x; int ti = threadIdx.x; int tk = threadIdx.z; int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; if (i>=dxNext) { return; } for (int k = tk; k < dz; k += blockDim.z){ deps[ti + k*K] = in[i + j*dxNext + k*dxNext*dyNext]; } __syncthreads(); // Low-Pass and High Pass Downsample int ind, lessThan, greaThan; for (int k = tk; k < dzNext; k += blockDim.z){ _data_t y = deps[0]-deps[0]; _data_t z = deps[0]-deps[0]; #pragma unroll for (int f = 0; f < filterLen; f++){ ind = 2*k+1 - (filterLen-1)+f; lessThan = (int) (ind<0); greaThan = (int) (ind>=dz); ind = -1*lessThan+ind*(-2*lessThan+1); ind = (2*dz-1)*greaThan+ind*(-2*greaThan+1); y += deps[ti + ind*K] * lod[filterLen-1-f]; z += deps[ti + ind*K] * hid[filterLen-1-f]; } Lz[i + j*dxNext + k*dxNext*dyNext] = y; Hz[i + j*dxNext + k*dxNext*dyNext] = z; } } extern "C" __global__ void cu_fwt3df_LC1(_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dxNext, int dyNext, int dzNext) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; scalar_t xGreatZero,yGreatZero,zGreatZero; if ((i>=dxNext)||(j>=dyNext)||(k>=dzNext)) { return; } //HLL x = HxLyLz_df1[i+j*dxNext+k*dxNext*dyNext]; y = HxLyLz_df2[i+j*dxNext+k*dxNext*dyNext]; z = HxLyLz_n[i+j*dxNext+k*dxNext*dyNext]; HxLyLz_df1[i+j*dxNext+k*dxNext*dyNext] = y; HxLyLz_df2[i+j*dxNext+k*dxNext*dyNext] = z; yGreatZero = j>0; zGreatZero = k>0; HxLyLz_n[i+j*dxNext+k*dxNext*dyNext] = x + yGreatZero*0.25f*y + zGreatZero*0.25f*z; //LHL x = LxHyLz_df1[i+j*dxNext+k*dxNext*dyNext]; y = LxHyLz_df2[i+j*dxNext+k*dxNext*dyNext]; z = LxHyLz_n[i+j*dxNext+k*dxNext*dyNext]; LxHyLz_df2[i+j*dxNext+k*dxNext*dyNext] = z; xGreatZero = i>0; zGreatZero = k>0; LxHyLz_n[i+j*dxNext+k*dxNext*dyNext] = y + xGreatZero*0.25f*x + zGreatZero*0.25f*z; //LLH x = LxLyHz_df1[i+j*dxNext+k*dxNext*dyNext]; y = LxLyHz_df2[i+j*dxNext+k*dxNext*dyNext]; z = LxLyHz_n[i+j*dxNext+k*dxNext*dyNext]; LxLyHz_df1[i+j*dxNext+k*dxNext*dyNext] = y; LxLyHz_df2[i+j*dxNext+k*dxNext*dyNext] = x; yGreatZero = j>0; xGreatZero = i>0; LxLyHz_n[i+j*dxNext+k*dxNext*dyNext] = z + yGreatZero*0.25*y + xGreatZero*0.25*x; } extern "C" __global__ void cu_fwt3df_LC1_diff(_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dxNext, int dyNext, int dzNext) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; _data_t zero = make_float2(0.f,0.f); if ((i>=dxNext)||(j>=dyNext)||(k>=dzNext)) { return; } //HLL if (j>0) y = HxLyLz_df1[i+(j-1)*dxNext+k*dxNext*dyNext]; else y = zero; if (k>0) z = HxLyLz_df2[i+j*dxNext+(k-1)*dxNext*dyNext]; else z = zero; HxLyLz_n[i+j*dxNext+k*dxNext*dyNext] += -0.25*y - 0.25*z; //LHL if (i>0) x = LxHyLz_df1[(i-1)+j*dxNext+k*dxNext*dyNext]; else x = zero; if (k>0) z = LxHyLz_df2[i+j*dxNext+(k-1)*dxNext*dyNext]; else z = zero; LxHyLz_n[i+j*dxNext+k*dxNext*dyNext] += -0.25*x - 0.25*z; //LLH if (j>0) y = LxLyHz_df1[i+(j-1)*dxNext+k*dxNext*dyNext]; else y = zero; if (i>0) x = LxLyHz_df2[(i-1)+j*dxNext+k*dxNext*dyNext]; else x = zero; LxLyHz_n[i+j*dxNext+k*dxNext*dyNext] += -0.25*y - 0.25*x; } extern "C" __global__ void cu_fwt3df_LC2(_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dxNext, int dyNext, int dzNext) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; scalar_t xGreatZero,yGreatZero,zGreatZero; if ((i>=dxNext)||(j>=dyNext)||(k>=dzNext)) { return; } //HHL x = HxHyLz_df1[i+j*dxNext+k*dxNext*dyNext]; y = HxHyLz_df2[i+j*dxNext+k*dxNext*dyNext]; z = HxHyLz_n[i+j*dxNext+k*dxNext*dyNext]; HxHyLz_df1[i+j*dxNext+k*dxNext*dyNext] = 0.5*(x-y); HxHyLz_df2[i+j*dxNext+k*dxNext*dyNext] = z; zGreatZero = k>0; HxHyLz_n[i+j*dxNext+k*dxNext*dyNext] = 0.5*(x+y) + zGreatZero*0.125*z; //HLH x = HxLyHz_df1[i+j*dxNext+k*dxNext*dyNext]; y = HxLyHz_df2[i+j*dxNext+k*dxNext*dyNext]; z = HxLyHz_n[i+j*dxNext+k*dxNext*dyNext]; HxLyHz_df1[i+j*dxNext+k*dxNext*dyNext] = 0.5*(z-x); HxLyHz_df2[i+j*dxNext+k*dxNext*dyNext] = y; yGreatZero = j>0; HxLyHz_n[i+j*dxNext+k*dxNext*dyNext] = 0.5*(z+x) + yGreatZero*0.125*y; //LHH x = LxHyHz_df1[i+j*dxNext+k*dxNext*dyNext]; y = LxHyHz_df2[i+j*dxNext+k*dxNext*dyNext]; z = LxHyHz_n[i+j*dxNext+k*dxNext*dyNext]; LxHyHz_df1[i+j*dxNext+k*dxNext*dyNext] = 0.5*(y-z); LxHyHz_df2[i+j*dxNext+k*dxNext*dyNext] = x; xGreatZero = i>0; LxHyHz_n[i+j*dxNext+k*dxNext*dyNext] = 0.5*(y+z) + xGreatZero*0.125*x; } extern "C" __global__ void cu_fwt3df_LC2_diff(_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dxNext, int dyNext, int dzNext) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; _data_t zero = make_float2(0.f,0.f); if ((i>=dxNext)||(j>=dyNext)||(k>=dzNext)) { return; } //HHL if (k>0) z = HxHyLz_df2[i+j*dxNext+(k-1)*dxNext*dyNext]; else z = zero; HxHyLz_n[i+j*dxNext+k*dxNext*dyNext] += -0.125*z; //HLH if (j>0) y = HxLyHz_df2[i+(j-1)*dxNext+k*dxNext*dyNext]; else y = zero; HxLyHz_n[i+j*dxNext+k*dxNext*dyNext] += -0.125*y; //LHH if (i>0) x = LxHyHz_df2[(i-1)+j*dxNext+k*dxNext*dyNext]; else x = zero; LxHyHz_n[i+j*dxNext+k*dxNext*dyNext] += -0.125*x; } extern "C" __global__ void cu_fwt3df_LC3(_data_t* HxHyHz_df1,_data_t* HxHyHz_df2,_data_t* HxHyHz_n,int dxNext, int dyNext, int dzNext) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; if ((i>=dxNext)||(j>=dyNext)||(k>=dzNext)) { return; } //HHH x = HxHyHz_df1[i+j*dxNext+k*dxNext*dyNext]; y = HxHyHz_df2[i+j*dxNext+k*dxNext*dyNext]; z = HxHyHz_n[i+j*dxNext+k*dxNext*dyNext]; HxHyHz_df1[i+j*dxNext+k*dxNext*dyNext] = 1.0/3.0*(-2.0*x+y+z); HxHyHz_df2[i+j*dxNext+k*dxNext*dyNext] = 1.0/3.0*(2*y-x-z); HxHyHz_n[i+j*dxNext+k*dxNext*dyNext] = 1.0/3.0*(x+y+z); } // ############################################################################ // CUDA function of iwt depth convolution. // Loads data to scratchpad (shared memory) and convolve w/ low pass and high pass // Scratchpad size: K x 2*dy // Output: Lz/Hz // Input: LxLy,LxHy / HxLy, HxHy, dx, dy, dxNext, dyNext,xOffset, yOffset,lod, hid, filterLen // ############################################################################ extern "C" __global__ void cu_iwt3df_dep(_data_t *out, _data_t *Lz, _data_t *Hz, int dx, int dy,int dz,int dxNext, int dyNext, int dzNext,int xOffset, int yOffset,int zOffset,scalar_t *lod, scalar_t *hid, int filterLen) { extern __shared__ _data_t deps []; int const K = blockDim.x; int ti = threadIdx.x; int tk = threadIdx.z; int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; if (i>=dx){ return; } for (int k = tk; k < dz; k += blockDim.z){ deps[ti + k*K] = Lz[i + j*dx + k*dx*dy]; deps[ti + (k+dz)*K] = Hz[i + j*dx + k*dx*dy]; } __syncthreads(); // Low-Pass and High Pass Downsample int ind; for (int k = tk+zOffset; k < dzNext+zOffset; k += blockDim.z){ _data_t y = deps[0]-deps[0]; #pragma unroll for (int f = (k-(filterLen-1)) % 2; f < filterLen; f+=2){ ind = (k-(filterLen-1)+f)>>1; if ((ind >= 0) && (ind < dz)) { y += deps[ti + ind*K] * lod[filterLen-1-f]; y += deps[ti + (ind+dz)*K] * hid[filterLen-1-f]; } } out[i + j*dx + (k-zOffset)*dx*dy] = y; } } // ############################################################################ // CUDA function of iwt row convolution. Assumes fwt_col() has already been called. // Loads data to scratchpad (shared memory) and convolve w/ low pass and high pass // Scratchpad size: K x 2*dy // Output: Lx/Hx // Input: LxLy,LxHy / HxLy, HxHy, dx, dy, dxNext, dyNext,xOffset, yOffset,lod, hid, filterLen // ############################################################################ extern "C" __global__ void cu_iwt3df_row(_data_t *out, _data_t *Ly, _data_t *Hy, int dx, int dy,int dz,int dxNext, int dyNext,int dzNext,int xOffset, int yOffset, int zOffset,scalar_t *lod, scalar_t *hid, int filterLen) { extern __shared__ _data_t rows []; int const K = blockDim.x; int ti = threadIdx.x; int tj = threadIdx.y; int i = blockIdx.x*blockDim.x+threadIdx.x; int k = blockIdx.z*blockDim.z+threadIdx.z; if (i>=dx){ return; } for (int j = tj; j < dy; j += blockDim.y){ rows[ti + j*K] = Ly[i + j*dx + k*dx*dy]; rows[ti + (j+dy)*K] = Hy[i + j*dx + k*dx*dy]; } __syncthreads(); // Low-Pass and High Pass Downsample int ind; for (int j = tj+yOffset; j < dyNext+yOffset; j += blockDim.y){ _data_t y = rows[0]-rows[0]; #pragma unroll for (int f = (j-(filterLen-1)) % 2; f < filterLen; f+=2){ ind = (j-(filterLen-1)+f)>>1; if ((ind >= 0) && (ind < dy)) { y += rows[ti + ind*K] * lod[filterLen-1-f]; y += rows[ti + (ind+dy)*K] * hid[filterLen-1-f]; } } out[i + (j-yOffset)*dx + k*dx*dyNext] = y; } } // ############################################################################ // CUDA function of iwt column convolution // Loads data to scratchpad (shared memory) and convolve w/ low pass and high pass // Scratchpad size: 2*dx x K // Output: out // Input: Lx, Hx, dx, dy, dxNext, dyNext, lod, hid, filterLen // ############################################################################ extern "C" __global__ void cu_iwt3df_col(_data_t *out, _data_t *Lx, _data_t *Hx, int dx, int dy,int dz,int dxNext, int dyNext, int dzNext,int xOffset, int yOffset, int zOffset,scalar_t *lod, scalar_t *hid, int filterLen) { extern __shared__ _data_t cols []; int ti = threadIdx.x; int tj = threadIdx.y; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; if (j>=dyNext){ return; } int dx2 = 2*dx; // Load Input to Temp Array for (int i = ti; i < dx; i += blockDim.x){ cols[i + tj*dx2] = Lx[i + j*dx + k*dx*dyNext]; cols[dx+i + tj*dx2] = Hx[i + j*dx + k*dx*dyNext]; } __syncthreads(); // Low-Pass and High Pass Downsample int ind; for (int i = ti+xOffset; i < dxNext+xOffset; i += blockDim.x){ _data_t y = cols[0]-cols[0]; #pragma unroll for (int f = (i-(filterLen-1)) % 2; f < filterLen; f+=2){ ind = (i-(filterLen-1)+f)>>1; if (ind >= 0 && ind < dx) { y += cols[ind + tj*dx2] * lod[filterLen-1-f]; y += cols[dx+ind + tj*dx2] * hid[filterLen-1-f]; } } out[(i-xOffset) + j*dxNext + k*dxNext*dyNext] = y; } } extern "C" __global__ void cu_iwt3df_LC1 (_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dx, int dy, int dz) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t df1,df2,n; scalar_t xGreatZero,yGreatZero,zGreatZero; if ((i>=dx)||(j>=dy)||(k>=dz)) { return; } //HLL df1 = HxLyLz_df1[i+j*dx+k*dx*dy]; df2 = HxLyLz_df2[i+j*dx+k*dx*dy]; n = HxLyLz_n[i+j*dx+k*dx*dy]; HxLyLz_df2[i+j*dx+k*dx*dy] = df1; HxLyLz_n[i+j*dx+k*dx*dy] = df2; yGreatZero = j>0; zGreatZero = k>0; HxLyLz_df1[i+j*dx+k*dx*dy] = n - yGreatZero*0.25*df1 - zGreatZero*0.25*df2; //LHL df1 = LxHyLz_df1[i+j*dx+k*dx*dy]; df2 = LxHyLz_df2[i+j*dx+k*dx*dy]; n = LxHyLz_n[i+j*dx+k*dx*dy]; LxHyLz_n[i+j*dx+k*dx*dy] = df2; xGreatZero = i>0; zGreatZero = k>0; LxHyLz_df2[i+j*dx+k*dx*dy] = n - xGreatZero*0.25*df1 - zGreatZero*0.25*df2; //LLH df1 = LxLyHz_df1[i+j*dx+k*dx*dy]; df2 = LxLyHz_df2[i+j*dx+k*dx*dy]; n = LxLyHz_n[i+j*dx+k*dx*dy]; LxLyHz_df1[i+j*dx+k*dx*dy] = df2; LxLyHz_df2[i+j*dx+k*dx*dy] = df1; yGreatZero = j>0; xGreatZero = i>0; LxLyHz_n[i+j*dx+k*dx*dy] = n - yGreatZero*0.25*df1 - xGreatZero*0.25*df2; } extern "C" __global__ void cu_iwt3df_LC1_diff (_data_t *HxLyLz_df1,_data_t *HxLyLz_df2,_data_t *HxLyLz_n,_data_t *LxHyLz_df1,_data_t *LxHyLz_df2,_data_t *LxHyLz_n,_data_t *LxLyHz_df1,_data_t *LxLyHz_df2,_data_t *LxLyHz_n,int dx, int dy, int dz) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; _data_t zero = make_float2(0.f,0.f); if ((i>=dx)||(j>=dy)||(k>=dz)) { return; } //HLL if (j>0) y = HxLyLz_df2[i+(j-1)*dx+k*dx*dy]; else y = zero; if (k>0) z = HxLyLz_n[i+j*dx+(k-1)*dx*dy]; else z = zero; HxLyLz_df1[i+j*dx+k*dx*dy] += 0.25*y + 0.25*z; //LHL if (i>0) x = LxHyLz_df1[(i-1)+j*dx+k*dx*dy]; else x = zero; if (k>0) z = LxHyLz_n[i+j*dx+(k-1)*dx*dy]; else z = zero; LxHyLz_df2[i+j*dx+k*dx*dy] += 0.25*x + 0.25*z; //LLH if (j>0) y = LxLyHz_df2[i+(j-1)*dx+k*dx*dy]; else y = zero; if (i>0) x = LxLyHz_df1[(i-1)+j*dx+k*dx*dy]; else x = zero; LxLyHz_n[i+j*dx+k*dx*dy] += 0.25*y + 0.25*x; } extern "C" __global__ void cu_iwt3df_LC2 (_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dx, int dy, int dz) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t df1,df2,n; scalar_t xGreatZero,yGreatZero,zGreatZero; if ((i>=dx)||(j>=dy)||(k>=dz)) { return; } //HHL df1 = HxHyLz_df1[i+j*dx+k*dx*dy]; df2 = HxHyLz_df2[i+j*dx+k*dx*dy]; n = HxHyLz_n[i+j*dx+k*dx*dy]; HxHyLz_n[i+j*dx+k*dx*dy] = df2; zGreatZero = k>0; HxHyLz_df1[i+j*dx+k*dx*dy] = df1+n-zGreatZero*0.125*df2; HxHyLz_df2[i+j*dx+k*dx*dy] = n-df1-zGreatZero*0.125*df2; //HLH df1 = HxLyHz_df1[i+j*dx+k*dx*dy]; df2 = HxLyHz_df2[i+j*dx+k*dx*dy]; n = HxLyHz_n[i+j*dx+k*dx*dy]; HxLyHz_df2[i+j*dx+k*dx*dy] = df2; yGreatZero = j>0; HxLyHz_n[i+j*dx+k*dx*dy] = df1+n-yGreatZero*0.125*df2; HxLyHz_df1[i+j*dx+k*dx*dy] = n-df1-yGreatZero*0.125*df2; //LHH df1 = LxHyHz_df1[i+j*dx+k*dx*dy]; df2 = LxHyHz_df2[i+j*dx+k*dx*dy]; n = LxHyHz_n[i+j*dx+k*dx*dy]; LxHyHz_df1[i+j*dx+k*dx*dy] = df2; xGreatZero = i>0; LxHyHz_df2[i+j*dx+k*dx*dy] = df1+n-xGreatZero*0.125*df2; LxHyHz_n[i+j*dx+k*dx*dy] = n-df1-xGreatZero*0.125*df2; } extern "C" __global__ void cu_iwt3df_LC2_diff (_data_t* HxHyLz_df1,_data_t* HxHyLz_df2,_data_t* HxHyLz_n,_data_t* HxLyHz_df1,_data_t* HxLyHz_df2,_data_t* HxLyHz_n,_data_t* LxHyHz_df1,_data_t* LxHyHz_df2,_data_t* LxHyHz_n,int dx, int dy, int dz) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t x,y,z; _data_t zero = make_float2(0.f,0.f); if ((i>=dx)||(j>=dy)||(k>=dz)) { return; } //HHL if (k>0) z = HxHyLz_n[i+j*dx+(k-1)*dx*dy]; else z = zero; HxHyLz_df1[i+j*dx+k*dx*dy] += 0.125*z; HxHyLz_df2[i+j*dx+k*dx*dy] += 0.125*z; //HLH if (j>0) y = HxLyHz_df2[i+(j-1)*dx+k*dx*dy]; else y = zero; HxLyHz_df1[i+j*dx+k*dx*dy] += 0.125*y; HxLyHz_n[i+j*dx+k*dx*dy] += 0.125*y; //LHH if (i>0) x = LxHyHz_df1[(i-1)+j*dx+k*dx*dy]; else x = zero; LxHyHz_df2[i+j*dx+k*dx*dy] += 0.125*x; LxHyHz_n[i+j*dx+k*dx*dy] += 0.125*x; } extern "C" __global__ void cu_iwt3df_LC3 (_data_t* HxHyHz_df1,_data_t* HxHyHz_df2,_data_t* HxHyHz_n,int dx, int dy, int dz) { int i = blockIdx.x*blockDim.x+threadIdx.x; int j = blockIdx.y*blockDim.y+threadIdx.y; int k = blockIdx.z*blockDim.z+threadIdx.z; _data_t df1,df2,n; if ((i>=dx)||(j>=dy)||(k>=dz)) { return; } //HHH df1 = HxHyHz_df1[i+j*dx+k*dx*dy]; df2 = HxHyHz_df2[i+j*dx+k*dx*dy]; n = HxHyHz_n[i+j*dx+k*dx*dy]; HxHyHz_df1[i+j*dx+k*dx*dy] = n-df1; HxHyHz_df2[i+j*dx+k*dx*dy] = df2+n; HxHyHz_n[i+j*dx+k*dx*dy] = df1-df2+n; } extern "C" __global__ void cu_mult(_data_t* in, _data_t mult, int maxInd) { int ind = blockIdx.x*blockDim.x+threadIdx.x; if (ind > maxInd) { return; } in[ind] = in[ind]*mult; } extern "C" __global__ void cu_add_mult(_data_t* out, _data_t* in, _data_t mult, int maxInd) { int ind = blockIdx.x*blockDim.x+threadIdx.x; if (ind > maxInd) { return; } _data_t i = out[ind]; out[ind] = i+(out[ind]-i)*mult; } __global__ void cu_soft_thresh (_data_t* in, scalar_t thresh, int numMax) { int const i = threadIdx.x + blockDim.x*blockIdx.x; if (i>numMax) return; scalar_t norm = abs(in[i]); scalar_t red = norm - thresh; in[i] = (red > 0.f) ? ((red / norm) * (in[i])) : in[i]-in[i]; } __global__ void cu_circshift(_data_t* data, _data_t* dataCopy, int dx, int dy, int dz,int shift1, int shift2,int shift3) { int index = blockIdx.x*blockDim.x + threadIdx.x; if (index >= dx*dy*dz) { return; } int indexShifted = (index+shift1+shift2*dx+shift3*dx*dy)%(dx*dy*dz); data[indexShifted] = dataCopy[index]; } __global__ void cu_circunshift(_data_t* data, _data_t* dataCopy, int dx, int dy, int dz,int shift1, int shift2,int shift3) { int index = blockIdx.x*blockDim.x + threadIdx.x; if (index >= dx*dy*dz) { return; } int indexShifted = (index+shift1+shift2*dx+shift3*dx*dy)%(dx*dy*dz); data[index] = dataCopy[indexShifted]; } bart-0.5.00/src/dfwavelet/dfwavelet_kernels.h000066400000000000000000000041331353046746100211630ustar00rootroot00000000000000/* * Copyright 2013-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus extern "C" { #endif struct dfwavelet_plan_s; /* GPU Host Funcstion */ extern void dffwt3_gpuHost(struct dfwavelet_plan_s* plan, _Complex float* out_wcdf1,_Complex float* out_wcdf2,_Complex float* out_wcn, _Complex float* in_vx,_Complex float* in_vy,_Complex float* in_vz); extern void dfiwt3_gpuHost(struct dfwavelet_plan_s* plan, _Complex float* out_vx,_Complex float* out_vy,_Complex float* out_vz, _Complex float* in_wcdf1,_Complex float* in_wcdf2,_Complex float* in_wcn); extern void dfsoftthresh_gpuHost(struct dfwavelet_plan_s* plan,float dfthresh, float nthresh, _Complex float* out_wcdf1,_Complex float* out_wcdf2,_Complex float* out_wcn); extern void dfwavthresh3_gpuHost(struct dfwavelet_plan_s* plan,float dfthresh, float nthresh,_Complex float* out_vx,_Complex float* out_vy,_Complex float* out_vz,_Complex float* in_vx,_Complex float* in_vy,_Complex float* in_vz); /* GPU Funcstion */ extern void dffwt3_gpu(struct dfwavelet_plan_s* plan, _Complex float* out_wcdf1,_Complex float* out_wcdf2,_Complex float* out_wcn, _Complex float* in_vx,_Complex float* in_vy,_Complex float* in_vz); extern void dfiwt3_gpu(struct dfwavelet_plan_s* plan, _Complex float* out_vx,_Complex float* out_vy,_Complex float* out_vz, _Complex float* in_wcdf1,_Complex float* in_wcdf2,_Complex float* in_wcn); extern void dfsoftthresh_gpu(struct dfwavelet_plan_s* plan,float dfthresh, float nthresh, _Complex float* out_wcdf1,_Complex float* out_wcdf2,_Complex float* out_wcn); extern void dfwavthresh3_gpu(struct dfwavelet_plan_s* plan,float dfthresh, float nthresh,_Complex float* out_vx,_Complex float* out_vy,_Complex float* out_vz,_Complex float* in_vx,_Complex float* in_vy,_Complex float* in_vz); extern void circshift_gpu(struct dfwavelet_plan_s* plan, _Complex float* data); extern void circunshift_gpu(struct dfwavelet_plan_s* plan, _Complex float* data); #ifdef __cplusplus } #endif bart-0.5.00/src/dfwavelet/prox_dfwavelet.c000066400000000000000000000322321353046746100205040ustar00rootroot00000000000000/* * Copyright 2013-2015 The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Frank Ong * 2016 Martin Uecker * * Ong F, Uecker M, Tariq U, Hsiao A, Alley MT, Vasanawala SS, Lustig M. * Robust 4D Flow Denoising using Divergence-free Wavelet Transform, * Magn Reson Med 2015; 73: 828-842. */ #define _GNU_SOURCE #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops_p.h" #include "num/ops.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/mri.h" #include "linops/linop.h" #include "linops/waveop.h" #include "iter/thresh.h" #include "dfwavelet.h" #include "prox_dfwavelet.h" static void prox_dfwavelet_del(const operator_data_t* _data); static void prox_dfwavelet_thresh(const operator_data_t* _data, float thresh, complex float* out, const complex float* in); static struct prox_dfwavelet_data* prepare_prox_dfwavelet_data(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu); static void prox_4pt_dfwavelet_del(const operator_data_t* _data); static void prox_4pt_dfwavelet_thresh(const operator_data_t* _data, float thresh, complex float* out, const complex float* in); static struct prox_4pt_dfwavelet_data* prepare_prox_4pt_dfwavelet_data(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu); struct prox_dfwavelet_data { INTERFACE(operator_data_t); bool use_gpu; unsigned int slice_flag; unsigned int flow_dim; float lambda; long im_dims[DIMS]; long tim_dims[DIMS]; long im_strs[DIMS]; complex float* vx; complex float* vy; complex float* vz; struct dfwavelet_plan_s* plan; }; static DEF_TYPEID(prox_dfwavelet_data); const struct operator_p_s* prox_dfwavelet_create(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu) { struct prox_dfwavelet_data* data = prepare_prox_dfwavelet_data(im_dims, min_size, res, flow_dim, lambda, use_gpu); return operator_p_create(DIMS, im_dims, DIMS, im_dims, CAST_UP(data), prox_dfwavelet_thresh, prox_dfwavelet_del); } struct prox_dfwavelet_data* prepare_prox_dfwavelet_data(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu) { // get dimension PTR_ALLOC(struct prox_dfwavelet_data, data); SET_TYPEID(prox_dfwavelet_data, data); md_copy_dims(DIMS, data->im_dims, im_dims); md_select_dims(DIMS, FFT_FLAGS, data->tim_dims, im_dims); md_calc_strides(DIMS, data->im_strs, im_dims, CFL_SIZE); // initialize temp #ifdef USE_CUDA if (use_gpu) { data->vx = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->vy = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->vz = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); } else #endif { data->vx = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->vy = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->vz = md_alloc(DIMS, data->tim_dims, CFL_SIZE); } data->flow_dim = flow_dim; data->slice_flag = ~FFT_FLAGS; data->lambda = lambda; data->plan = prepare_dfwavelet_plan(3, data->tim_dims, (long*) min_size, (complex float*) res, use_gpu); return PTR_PASS(data); } static void prox_dfwavelet_del(const operator_data_t* _data) { auto data = CAST_DOWN(prox_dfwavelet_data, _data); md_free(data->vx); md_free(data->vy); md_free(data->vz); dfwavelet_free(data->plan); free(data); } static void prox_dfwavelet_thresh(const operator_data_t* _data, float thresh, complex float* out, const complex float* in) { auto data = CAST_DOWN(prox_dfwavelet_data, _data); bool done = false; long pos[DIMS]; md_set_dims(DIMS, pos, 0); while (!done) { // copy vx, vy, vz md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->vx, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->vy, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->vz, in, CFL_SIZE); pos[data->flow_dim]=0; // threshold dfwavelet_thresh(data->plan, thresh * data->lambda, thresh* data->lambda, data->vx, data->vy, data->vz, data->vx, data->vy, data->vz); // copy vx, vy, vz md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->vx, CFL_SIZE); pos[data->flow_dim]++; md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->vy, CFL_SIZE); pos[data->flow_dim]++; md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->vz, CFL_SIZE); pos[data->flow_dim]=0; // increment pos long carryon = 1; for (unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(data->slice_flag & ~MD_BIT(data->flow_dim), i)) { pos[i] += carryon; if (pos[i] < data->im_dims[i]) { carryon = 0; break; } else { carryon = 1; pos[i] = 0; } } } done = carryon; } } struct prox_4pt_dfwavelet_data { INTERFACE(operator_data_t); bool use_gpu; unsigned int slice_flag; unsigned int flow_dim; float lambda; long im_dims[DIMS]; long tim_dims[DIMS]; long im_strs[DIMS]; complex float* vx; complex float* vy; complex float* vz; complex float* ph0; complex float* pc0; complex float* pc1; complex float* pc2; complex float* pc3; struct dfwavelet_plan_s* plan; const struct linop_s* w_op; const struct operator_p_s* wthresh_op; }; static DEF_TYPEID(prox_4pt_dfwavelet_data); const struct operator_p_s* prox_4pt_dfwavelet_create(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu) { struct prox_4pt_dfwavelet_data* data = prepare_prox_4pt_dfwavelet_data(im_dims, min_size, res, flow_dim, lambda, use_gpu); return operator_p_create(DIMS, im_dims, DIMS, im_dims, CAST_UP(data), prox_4pt_dfwavelet_thresh, prox_4pt_dfwavelet_del); } struct prox_4pt_dfwavelet_data* prepare_prox_4pt_dfwavelet_data(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, bool use_gpu) { PTR_ALLOC(struct prox_4pt_dfwavelet_data, data); SET_TYPEID(prox_4pt_dfwavelet_data, data); md_copy_dims(DIMS, data->im_dims, im_dims); md_select_dims(DIMS, FFT_FLAGS, data->tim_dims, im_dims); md_calc_strides(DIMS, data->im_strs, im_dims, CFL_SIZE); assert(4 == im_dims[flow_dim]); // initialize temp #ifdef USE_CUDA if (use_gpu) { data->vx = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->vy = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->vz = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->ph0 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc0 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc1 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc2 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); data->pc3 = md_alloc_gpu(DIMS, data->tim_dims, CFL_SIZE); } else #endif { data->vx = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->vy = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->vz = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->ph0 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc0 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc1 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc2 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); data->pc3 = md_alloc(DIMS, data->tim_dims, CFL_SIZE); } data->flow_dim = flow_dim; data->slice_flag = ~FFT_FLAGS; data->lambda = lambda; data->plan = prepare_dfwavelet_plan(3, data->tim_dims, (long*) min_size, (complex float*) res, use_gpu); long strs[DIMS]; md_calc_strides(DIMS, strs, data->tim_dims, CFL_SIZE); data->w_op = linop_wavelet_create(DIMS, FFT_FLAGS, data->tim_dims, strs, min_size, false); data->wthresh_op = prox_unithresh_create(DIMS, data->w_op, lambda, MD_BIT(data->flow_dim)); return PTR_PASS(data); } static void prox_4pt_dfwavelet_del(const operator_data_t* _data) { auto data = CAST_DOWN(prox_4pt_dfwavelet_data, _data); md_free(data->vx); md_free(data->vy); md_free(data->vz); md_free(data->ph0); md_free(data->pc0); md_free(data->pc1); md_free(data->pc2); md_free(data->pc3); dfwavelet_free(data->plan); operator_p_free(data->wthresh_op); linop_free(data->w_op); free(data); } static void prox_4pt_dfwavelet_thresh(const operator_data_t* _data, float thresh, complex float* out, const complex float* in) { auto data = CAST_DOWN(prox_4pt_dfwavelet_data, _data); bool done = false; long pos[DIMS]; md_set_dims(DIMS, pos, 0); while (!done) { // copy pc md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc0, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc1, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc2, in, CFL_SIZE); pos[data->flow_dim]++; md_slice(DIMS, data->slice_flag, pos, data->im_dims, data->pc3, in, CFL_SIZE); pos[data->flow_dim] = 0; // pc to velocity // TODO: Make gpu for (int i = 0; i < md_calc_size(DIMS, data->tim_dims); i++) { data->vx[i] = (data->pc1[i] - data->pc0[i]) / 2; data->vy[i] = (data->pc2[i] - data->pc1[i]) / 2; data->vz[i] = (data->pc3[i] - data->pc2[i]) / 2; data->ph0[i] = (data->pc0[i] + data->pc3[i]) / 2; } // threshold dfwavelet_thresh(data->plan, thresh * data->lambda, thresh* data->lambda, data->vx, data->vy, data->vz, data->vx, data->vy, data->vz); operator_p_apply(data->wthresh_op, thresh, DIMS, data->tim_dims, data->ph0, DIMS, data->tim_dims, data->ph0); // velocity to pc for (int i = 0; i < md_calc_size(DIMS, data->tim_dims ); i++) { data->pc0[i] = (- data->vx[i] - data->vy[i] - data->vz[i] + data->ph0[i]); data->pc1[i] = (+ data->vx[i] - data->vy[i] - data->vz[i] + data->ph0[i]); data->pc2[i] = (+ data->vx[i] + data->vy[i] - data->vz[i] + data->ph0[i]); data->pc3[i] = (+ data->vx[i] + data->vy[i] + data->vz[i] + data->ph0[i]); } // copy pc md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->pc0, CFL_SIZE); pos[data->flow_dim]++; md_copy_block(DIMS, pos, data->im_dims, out, data->tim_dims, data->pc1, CFL_SIZE); pos[data->flow_dim]++; md_copy_block( DIMS, pos, data->im_dims, out, data->tim_dims, data->pc2, CFL_SIZE ); pos[data->flow_dim]++; md_copy_block( DIMS, pos, data->im_dims, out, data->tim_dims, data->pc3, CFL_SIZE ); pos[data->flow_dim] = 0; // increment pos long carryon = 1; for(unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(data->slice_flag & ~MD_BIT(data->flow_dim), i)) { pos[i] += carryon; if (pos[i] < data->im_dims[i]) { carryon = 0; break; } else { carryon = 1; pos[i] = 0; } } } done = carryon; } } bart-0.5.00/src/dfwavelet/prox_dfwavelet.h000066400000000000000000000006521353046746100205120ustar00rootroot00000000000000 #include "misc/mri.h" #include "num/ops.h" extern const struct operator_p_s* prox_dfwavelet_create(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, _Bool use_gpu); extern const struct operator_p_s* prox_4pt_dfwavelet_create(const long im_dims[DIMS], const long min_size[3], const complex float res[3], unsigned int flow_dim, float lambda, _Bool use_gpu); bart-0.5.00/src/ecalib.c000066400000000000000000000136061353046746100147150ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2015-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2017 Martin Uecker * 2013 Dara Bahri * 2015 Siddharth Iyer */ #include #include #include #include #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "num/multind.h" #include "num/fft.h" #include "num/init.h" #include "calib/calib.h" #include "calib/estvar.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = " []"; static const char help_str[] = "Estimate coil sensitivities using ESPIRiT calibration.\n" "Optionally outputs the eigenvalue maps."; int main_ecalib(int argc, char* argv[]) { long calsize[3] = { 24, 24, 24 }; int maps = 2; bool one = false; bool calcen = false; bool print_svals = false; struct ecalib_conf conf = ecalib_defaults; const struct opt_s opts[] = { OPT_FLOAT('t', &conf.threshold, "threshold", "This determined the size of the null-space."), OPT_FLOAT('c', &conf.crop, "crop_value", "Crop the sensitivities if the eigenvalue is smaller than {crop_value}."), OPT_VEC3('k', &conf.kdims, "ksize", "kernel size"), OPT_VEC3('K', &conf.kdims, "", "()"), OPT_VEC3('r', &calsize, "cal_size", "Limits the size of the calibration region."), OPT_VEC3('R', &calsize, "", "()"), OPT_INT('m', &maps, "maps", "Number of maps to compute."), OPT_SET('S', &conf.softcrop, "create maps with smooth transitions (Soft-SENSE)."), OPT_SET('W', &conf.weighting, "soft-weighting of the singular vectors."), OPT_SET('I', &conf.intensity, "intensity correction"), OPT_SET('1', &one, "perform only first part of the calibration"), OPT_CLEAR('P', &conf.rotphase, "Do not rotate the phase with respect to the first principal component"), OPT_CLEAR('O', &conf.orthiter, "()"), OPT_FLOAT('b', &conf.perturb, "", "()"), OPT_SET('V', &print_svals, "()"), OPT_SET('C', &calcen, "()"), OPT_SET('g', &conf.usegpu, "()"), OPT_FLOAT('p', &conf.percentsv, "", "()"), OPT_INT('n', &conf.numsv, "", "()"), OPT_FLOAT('v', &conf.var, "variance", "Variance of noise in data."), OPT_SET('a', &conf.automate, "Automatically pick thresholds."), OPT_INT('d', &debug_level, "level", "Debug level"), }; cmdline(&argc, argv, 2, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (-1. != conf.percentsv) conf.threshold = -1.; if (-1 != conf.numsv) conf.threshold = -1.; if (conf.automate) { conf.crop = -1.; conf.weighting = true; } if (conf.weighting) { conf.numsv = -1.; conf.threshold = 0; conf.percentsv = -1.; conf.orthiter = false; } int N = DIMS; long ksp_dims[N]; complex float* in_data = load_cfl(argv[1], N, ksp_dims); // assert((kdims[0] < calsize_ro) && (kdims[1] < calsize_ro) && (kdims[2] < calsize_ro)); // assert((ksp_dims[0] == 1) || (calsize_ro < ksp_dims[0])); if (1 != ksp_dims[MAPS_DIM]) error("MAPS dimension is not of size one.\n"); long cal_dims[N]; complex float* cal_data = NULL; if (!calcen) { #ifdef USE_CC_EXTRACT_CALIB cal_data = cc_extract_calib(cal_dims, calsize, ksp_dims, in_data); #else cal_data = extract_calib(cal_dims, calsize, ksp_dims, in_data, false); #endif } else { for (int i = 0; i < 3; i++) cal_dims[i] = (calsize[i] < ksp_dims[i]) ? calsize[i] : ksp_dims[i]; for (int i = 3; i < N; i++) cal_dims[i] = ksp_dims[i]; cal_data = md_alloc(5, cal_dims, CFL_SIZE); md_resize_center(5, cal_dims, cal_data, ksp_dims, in_data, CFL_SIZE); } for (int i = 0; i < 3; i++) if (1 == ksp_dims[i]) conf.kdims[i] = 1; long channels = cal_dims[3]; unsigned int K = conf.kdims[0] * conf.kdims[1] * conf.kdims[2] * channels; float svals[K]; for (unsigned int i = 0; i < 3; i++) if ((1 == cal_dims[i]) && (1 != ksp_dims[i])) error("Calibration region not found!\n"); // To reproduce old results turn off rotation of phase. // conf.rotphase = false; // FIXME: we should scale the data (conf.usegpu ? num_init_gpu : num_init)(); if ((conf.var < 0.) && (conf.weighting || (conf.crop < 0.))) conf.var = estvar_calreg(conf.kdims, cal_dims, cal_data); if (one) { #if 0 long maps = out_dims[4]; assert(caldims[3] == out_dims[3]); assert(maps <= channels); #endif long cov_dims[4]; calone_dims(&conf, cov_dims, channels); complex float* imgcov = md_alloc(4, cov_dims, CFL_SIZE); calone(&conf, cov_dims, imgcov, K, svals, cal_dims, cal_data); complex float* out = create_cfl(argv[2], 4, cov_dims); md_copy(4, cov_dims, out, imgcov, CFL_SIZE); unmap_cfl(4, cov_dims, out); // caltwo(crthr, out_dims, out_data, emaps, cov_dims, imgcov, NULL, NULL); md_free(imgcov); } else { long out_dims[N]; long map_dims[N]; for (int i = 0; i < N; i++) { out_dims[i] = 1; map_dims[i] = 1; if ((i < 3) && (1 < conf.kdims[i])) { out_dims[i] = ksp_dims[i]; map_dims[i] = ksp_dims[i]; } } assert(maps <= ksp_dims[COIL_DIM]); out_dims[COIL_DIM] = ksp_dims[COIL_DIM]; out_dims[MAPS_DIM] = maps; map_dims[COIL_DIM] = 1; map_dims[MAPS_DIM] = maps; const char* emaps_file = NULL; if (4 == argc) emaps_file = argv[3]; complex float* out_data = create_cfl(argv[2], N, out_dims); complex float* emaps = (emaps_file ? create_cfl : anon_cfl)(emaps_file, N, map_dims); calib(&conf, out_dims, out_data, emaps, K, svals, cal_dims, cal_data); unmap_cfl(N, out_dims, out_data); unmap_cfl(N, map_dims, emaps); } if (print_svals) { for (unsigned int i = 0; i < K; i++) printf("SVALS %d %f\n", i, svals[i]); } printf("Done.\n"); unmap_cfl(N, ksp_dims, in_data); md_free(cal_data); return 0; } bart-0.5.00/src/ecaltwo.c000066400000000000000000000056141353046746100151340ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker */ #include #include #include "num/multind.h" #include "num/fft.h" #include "calib/calib.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/debug.h" #include "misc/opts.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "x y z []"; static const char help_str[] = "Second part of ESPIRiT calibration.\n" "Optionally outputs the eigenvalue maps."; int main_ecaltwo(int argc, char* argv[]) { long maps = 2; // channels; struct ecalib_conf conf = ecalib_defaults; const struct opt_s opts[] = { OPT_FLOAT('c', &conf.crop, "crop_value", "Crop the sensitivities if the eigenvalue is smaller than {crop_value}."), OPT_LONG('m', &maps, "maps", "Number of maps to compute."), OPT_SET('S', &conf.softcrop, "Create maps with smooth transitions (Soft-SENSE)."), OPT_CLEAR('O', &conf.orthiter, "()"), OPT_SET('g', &conf.usegpu, "()"), }; cmdline(&argc, argv, 5, 6, usage_str, help_str, ARRAY_SIZE(opts), opts); long in_dims[DIMS]; complex float* in_data = load_cfl(argv[4], DIMS, in_dims); int channels = 0; while (in_dims[3] != (channels * (channels + 1) / 2)) channels++; debug_printf(DP_INFO, "Channels: %d\n", channels); assert(maps <= channels); long out_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; long map_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; out_dims[0] = atoi(argv[1]); out_dims[1] = atoi(argv[2]); out_dims[2] = atoi(argv[3]); out_dims[3] = channels; out_dims[4] = maps; assert((out_dims[0] >= in_dims[0])); assert((out_dims[1] >= in_dims[1])); assert((out_dims[2] >= in_dims[2])); for (int i = 0; i < 3; i++) map_dims[i] = out_dims[i]; map_dims[3] = 1; map_dims[4] = maps; complex float* out_data = create_cfl(argv[5], DIMS, out_dims); complex float* emaps; if (7 == argc) emaps = create_cfl(argv[6], DIMS, map_dims); else emaps = md_alloc(DIMS, map_dims, CFL_SIZE); caltwo(&conf, out_dims, out_data, emaps, in_dims, in_data, NULL, NULL); if (conf.intensity) { debug_printf(DP_DEBUG1, "Normalize...\n"); normalizel1(DIMS, COIL_FLAG, out_dims, out_data); } debug_printf(DP_DEBUG1, "Crop maps... (%.2f)\n", conf.crop); crop_sens(out_dims, out_data, conf.softcrop, conf.crop, emaps); debug_printf(DP_DEBUG1, "Fix phase...\n"); fixphase(DIMS, out_dims, COIL_DIM, out_data, out_data); debug_printf(DP_INFO, "Done.\n"); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); if (7 == argc) unmap_cfl(DIMS, map_dims, emaps); else md_free(emaps); return 0; } bart-0.5.00/src/estdelay.c000066400000000000000000000342271353046746100153120ustar00rootroot00000000000000/* Copyright 2017-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker * 2018 Sebastian Rosenzweig * * * [1] * Kai Tobias Block and Martin Uecker, Simple Method for Adaptive * Gradient-Delay Compensation in Radial MRI, Annual Meeting ISMRM, * Montreal 2011, In Proc. Intl. Soc. Mag. Reson. Med 19: 2816 (2011) * * [2] * Amir Moussavi, Markus Untenberger, Martin Uecker, and Jens Frahm, * Correction of gradient-induced phase errors in radial MRI, * Magnetic Resonance in Medicine, 71:308-312 (2014) * * [3] * Sebastian Rosenzweig, Hans Christian Holme, Martin Uecker, * Simple Auto-Calibrated Gradient Delay Estimation From Few Spokes Using Radial * Intersections (RING), Preprint */ #include #include #include #include #include #ifdef RING_PAPER #include #endif #include "num/multind.h" #include "num/flpmath.h" #include "num/qform.h" #include "num/fft.h" #include "num/linalg.h" #include "num/init.h" #include "misc/debug.h" #include "misc/subpixel.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/mri.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif // [AC-Adaptive] static void radial_self_delays(unsigned int N, float shifts[N], const float phi[N], const long dims[DIMS], const complex float* in) { unsigned int d = 2; unsigned int flags = (1 << d); assert(N == dims[d]); long dims1[DIMS]; md_select_dims(DIMS, ~flags, dims1, dims); complex float* tmp1 = md_alloc(DIMS, dims1, CFL_SIZE); complex float* tmp2 = md_alloc(DIMS, dims1, CFL_SIZE); long pos[DIMS] = { 0 }; for (unsigned int i = 0; i < dims[d]; i++) { pos[d] = i; md_copy_block(DIMS, pos, dims1, tmp1, dims, in, CFL_SIZE); // find opposing spoke float mdelta = 0.; int mindex = 0; for (unsigned int j = 0; j < dims[d]; j++) { float delta = cabsf(cexpf(1.i * phi[j]) - cexpf(1.i * phi[i])); if (mdelta <= delta) { mdelta = delta; mindex = j; } } pos[d] = mindex; md_copy_block(DIMS, pos, dims1, tmp2, dims, in, CFL_SIZE); unsigned int d2 = 1; float rshifts[DIMS]; md_flip(DIMS, dims1, MD_BIT(d2), tmp2, tmp2, CFL_SIZE); // could be done by iFFT in est_subpixel_shift est_subpixel_shift(DIMS, rshifts, dims1, MD_BIT(d2), tmp2, tmp1); float mshift = rshifts[d2] / 2.; // mdelta shifts[i] = mshift; } md_free(tmp1); md_free(tmp2); } // [RING] Calculate Pseudoinverse static void calc_pinv(unsigned int Nint, complex float pinv[3][2 * Nint], const complex float A[2 * Nint][3]) { //AH complex float AH[3][2 * Nint]; mat_transpose(2 * Nint, 3, AH, A); // (AH * A)^-1 complex float dot[3][3]; mat_mul(3, 2 * Nint, 3, dot, AH, A); complex float inv[3][3]; mat_inverse(3, inv, dot); // (AH * A)^-1 * AH mat_mul(3, 3, 2 * Nint, pinv, inv, AH); return; } // [RING] Find (nearly) orthogonal spokes static void find_intersec_sp(const unsigned int no_intersec_sp, long intersec_sp[no_intersec_sp], const unsigned int cur_idx, const unsigned int N, const float angles[N]) { float intersec_angles[no_intersec_sp]; for (unsigned int i = 0; i < no_intersec_sp; i++) { intersec_sp[i] = -1; intersec_angles[i] = FLT_MAX; } for (unsigned int i = 0; i < N; i++) { // Iterate through angles for (unsigned int j = 0; j < no_intersec_sp; j++) { // Iterate through intersec array // If angle difference of spoke 'i' and current spoke is greater than intersection angle 'j' if (fabs(fmod(fabs(angles[cur_idx] - angles[i]), M_PI) - M_PI / 2.) < intersec_angles[j]) { // Shift smaller intersec_angles to higher indices for (unsigned int k = no_intersec_sp; k > j + 1; k--) { intersec_sp[k - 1] = intersec_sp[k - 2]; // Spoke index intersec_angles[k - 1] = intersec_angles[k - 2]; // Angle value } // Assign current value intersec_sp[j] = i; intersec_angles[j] = fabs(fmod(fabs(angles[cur_idx]-angles[i]), M_PI) - M_PI / 2.); // Weight value break; } } } } // [RING] Test that hints if the chosen region (-r) is too small static void check_intersections(const unsigned int Nint, const unsigned int N, const complex float S_cmplx[3][1], const float angles[N], const long idx[2][Nint], const int c_region) { float phi0; float phi1; float N1; float N2; float l = 0; float m = 0; double S[3][1]; S[0][0] = creal(S_cmplx[0][0]); S[1][0] = creal(S_cmplx[1][0]); S[2][0] = creal(S_cmplx[2][0]); for (unsigned int i = 0; i < Nint; i++) { phi0 = angles[idx[0][i]]; phi1 = angles[idx[1][i]]; N1 = cosf(phi0) - cosf(phi1); N2 = sinf(phi0) - sinf(phi1); // Nominal distance from spoke center to intersection point // (analytical formula for intersection point) l = (S[0][0] * N1 + S[2][0] * N2 - cosf(phi1) / sinf(phi1) * (S[2][0] * N1 + S[1][0] * N2)) / (cosf(phi1) * sinf(phi0) / sinf(phi1) - cosf(phi0)); m = (S[0][0] * (-N1) + S[2][0] * (-N2) - cosf(phi0) / sinf(phi0) * (S[2][0] * (-N1) + S[1][0] * (-N2))) / (cosf(phi0) * sinf(phi1) / sinf(phi0) - cosf(phi1)); l = abs((int)round(l)); m = abs((int)round(m)); // Check if nominal distance can be reached in chosen region if ((l >= c_region / 2) || (m >= c_region / 2)) debug_printf(DP_WARN, "Choose larger region! (-r option)\n"); } } // [RING] Caclucate intersection points static void calc_intersections(unsigned int Nint, unsigned int N, unsigned int no_intersec_sp, float dist[2][Nint], long idx[2][Nint], const float angles[N], const long kc_dims[DIMS], const complex float* kc, const int ROI) { long spoke_dims[DIMS]; md_copy_dims(DIMS, spoke_dims, kc_dims); spoke_dims[PHS2_DIM] = 1; complex float* spoke_i = md_alloc(DIMS, spoke_dims, CFL_SIZE); complex float* spoke_j = md_alloc(DIMS, spoke_dims, CFL_SIZE); long pos_i[DIMS] = { 0 }; long pos_j[DIMS] = { 0 }; long coilPixel_dims[DIMS]; md_copy_dims(DIMS, coilPixel_dims, spoke_dims); coilPixel_dims[PHS1_DIM] = 1; complex float* coilPixel_l = md_alloc(DIMS, coilPixel_dims, CFL_SIZE); complex float* coilPixel_m = md_alloc(DIMS, coilPixel_dims, CFL_SIZE); complex float* diff = md_alloc(DIMS, coilPixel_dims, CFL_SIZE); long diff_rss_dims[DIMS]; md_copy_dims(DIMS, diff_rss_dims, coilPixel_dims); diff_rss_dims[COIL_DIM] = 1; diff_rss_dims[PHS1_DIM] = 1; complex float* diff_rss = md_alloc(DIMS, diff_rss_dims, CFL_SIZE); long pos_l[DIMS] = { 0 }; long pos_m[DIMS] = { 0 }; // Array to store indices of spokes that build an angle close to pi/2 with the current spoke long intersec_sp[no_intersec_sp]; for (unsigned int i = 0; i < no_intersec_sp; i++) intersec_sp[i] = -1; // Boundaries for spoke comparison int myROI = ROI; myROI += (ROI % 2 == 0) ? 1 : 0; // make odd int low = 0; int high = myROI - 1; int count = 0; // Intersection determination for (unsigned int i = 0; i < N; i++) { pos_i[PHS2_DIM] = i; md_slice(DIMS, PHS2_FLAG, pos_i, kc_dims, spoke_i, kc, CFL_SIZE); find_intersec_sp(no_intersec_sp, intersec_sp, i, N, angles); for (unsigned int j = 0; j < no_intersec_sp; j++) { pos_j[PHS2_DIM] = intersec_sp[j]; md_slice(DIMS, PHS2_FLAG, pos_j, kc_dims, spoke_j, kc, CFL_SIZE); idx[0][i * no_intersec_sp + j] = i; idx[1][i * no_intersec_sp + j] = intersec_sp[j]; // Elementwise rss comparisson float rss = FLT_MAX; for (int l = low; l <= high; l++) { pos_l[PHS1_DIM] = l; md_copy_block(DIMS, pos_l, coilPixel_dims, coilPixel_l, spoke_dims, spoke_i, CFL_SIZE); for (int m = low; m <= high; m++) { pos_m[PHS1_DIM] = m; md_copy_block(DIMS, pos_m, coilPixel_dims, coilPixel_m, spoke_dims, spoke_j, CFL_SIZE); md_zsub(DIMS, coilPixel_dims, diff, coilPixel_l, coilPixel_m); md_zrss(DIMS, coilPixel_dims, PHS1_FLAG|COIL_FLAG, diff_rss, diff); if (cabsf(diff_rss[0]) < rss) { // New minimum found rss = cabsf(diff_rss[0]); dist[0][i * no_intersec_sp + j] = (l + 1/2 - ROI/2); dist[1][i * no_intersec_sp + j] = (m + 1/2 - ROI/2); } } } count++; } } #ifdef RING_PAPER // Print projection angles and corresponding offsets to files const char* idx_out = "projangle.txt"; FILE* fp = fopen(idx_out, "w"); const char* d_out = "offset.txt"; FILE* fp1 = fopen(d_out, "w"); for (unsigned int i = 0; i < N; i++) { for (unsigned int j = 0; j < no_intersec_sp; j++) { fprintf(fp, "%f \t %f\n", angles[idx[0][i * no_intersec_sp + j]], angles[idx[1][i * no_intersec_sp + j]]); fprintf(fp1, "%f \t %f\n", dist[0][i * no_intersec_sp + j], dist[1][i * no_intersec_sp + j]); } } fclose(fp); fclose(fp1); #endif md_free(spoke_i); md_free(spoke_j); md_free(coilPixel_l); md_free(coilPixel_m); md_free(diff); md_free(diff_rss); } // [RING] Solve inverse problem AS = B using pseudoinverse static void calc_S(const unsigned int Nint, const unsigned int N, complex float S[3][1], const float angles[N], const float dist[2][Nint], const long idx[2][Nint]) { complex float A[2 * Nint][3]; float phi0 = 0; float phi1 = 0; float a0 = 0; float a1 = 0; float b0 = 0; float b1 = 0; complex float B[2 * Nint][1]; complex float alpha0 = 0; complex float alpha1 = 0; unsigned int count = 0; for (unsigned int i = 0; i < Nint; i++) { phi0 = angles[idx[0][i]]; phi1 = angles[idx[1][i]]; a0 = cosf(phi0) - cosf(phi1); a1 = sinf(phi0) - sinf(phi1); alpha0 = dist[0][i]; alpha1 = dist[1][i]; b0 = alpha1 * cosf(phi1) - alpha0 * cosf(phi0); b1 = alpha1 * sinf(phi1) - alpha0 * sinf(phi0); A[count][0] = a0; A[count][1] = 0.; A[count][2] = a1; B[count][0] = b0; count++; A[count][0] = 0.; A[count][1] = a1; A[count][2] = a0; B[count][0] = b1; count++; } complex float pinv[3][2 * Nint]; calc_pinv(Nint, pinv, A); mat_mul(3, 2 * Nint, 1, S, pinv, B); } static const char usage_str[] = " "; static const char help_str[] = "Estimate gradient delays from radial data."; int main_estdelay(int argc, char* argv[]) { bool ring = false; int pad_factor = 100; unsigned int no_intersec_sp = 1; float size = 1.5; const struct opt_s opts[] = { OPT_SET('R', &ring, "RING method"), OPT_INT('p', &pad_factor, "p", "[RING] Padding"), OPT_UINT('n', &no_intersec_sp, "n", "[RING] Number of intersecting spokes"), OPT_FLOAT('r', &size, "r", "[RING] Central region size"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); if (pad_factor % 2 != 0) error("Pad_factor -p should be even\n"); long tdims[DIMS]; const complex float* traj = load_cfl(argv[1], DIMS, tdims); long tdims1[DIMS]; md_select_dims(DIMS, ~MD_BIT(1), tdims1, tdims); complex float* traj1 = md_alloc(DIMS, tdims1, CFL_SIZE); md_slice(DIMS, MD_BIT(1), (long[DIMS]){ 0 }, tdims, traj1, traj, CFL_SIZE); unsigned int N = tdims[2]; float angles[N]; for (unsigned int i = 0; i < N; i++) angles[i] = M_PI + atan2f(crealf(traj1[3 * i + 0]), crealf(traj1[3 * i + 1])); if (ring) { assert(0 == tdims[1] % 2); md_slice(DIMS, MD_BIT(1), (long[DIMS]){ [1] = tdims[1] / 2 }, tdims, traj1, traj, CFL_SIZE); for (unsigned int i = 0; i < N; i++) if (0. != cabsf(traj1[3 * i])) error("Nominal trajectory must be centered for RING.\n"); } md_free(traj1); long full_dims[DIMS]; const complex float* full_in = load_cfl(argv[2], DIMS, full_dims); // Remove not needed dimensions long dims[DIMS]; md_select_dims(DIMS, READ_FLAG|PHS1_FLAG|PHS2_FLAG|COIL_FLAG, dims, full_dims); complex float* in = md_alloc(DIMS, dims, CFL_SIZE); long pos[DIMS] = { 0 }; md_copy_block(DIMS, pos, dims, in, full_dims, full_in, CFL_SIZE); // FIXME: more checks assert(dims[1] == tdims[1]); assert(dims[2] == tdims[2]); float delays[N]; if (!ring) { // AC-Adaptive method [1] radial_self_delays(N, delays, angles, dims, in); /* We allow an arbitrary quadratic form to account for * non-physical coordinate systems. * Moussavi et al., MRM 71:308-312 (2014) */ float qf[3]; fit_quadratic_form(qf, N, angles, delays); bart_printf("%f:%f:%f\n", qf[0], qf[1], qf[2]); } else { // RING method [3] int c_region = (int)(pad_factor * size); // Make odd to have 'Center of c_region' == 'DC component of spoke' c_region += (c_region % 2 == 0) ? 1 : 0; //--- Refine grid --- complex float* im = md_alloc(DIMS, dims, CFL_SIZE); ifftuc(DIMS, dims, PHS1_FLAG, im, in); long pad_dims[DIMS]; md_copy_dims(DIMS, pad_dims, dims); pad_dims[PHS1_DIM] = pad_factor * dims[PHS1_DIM]; complex float* k_pad = md_alloc(DIMS, pad_dims, CFL_SIZE); complex float* im_pad = md_alloc(DIMS, pad_dims, CFL_SIZE); md_resize_center(DIMS, pad_dims, im_pad, dims, im, CFL_SIZE); md_free(im); // Sinc filter in k-space (= crop FOV in image space) long crop_dims[DIMS]; md_copy_dims(DIMS, crop_dims, dims); crop_dims[PHS1_DIM] = 0.6 * dims[PHS1_DIM]; complex float* crop = md_alloc(DIMS, crop_dims, CFL_SIZE); md_zfill(DIMS, crop_dims, crop, 1.); complex float* mask = md_alloc(DIMS, pad_dims, CFL_SIZE); md_resize_center(DIMS, pad_dims, mask, crop_dims, crop, CFL_SIZE); complex float* im_pad2 = md_alloc(DIMS, pad_dims, CFL_SIZE); md_zmul(DIMS, pad_dims, im_pad2, im_pad, mask); md_free(im_pad); md_free(mask); fftuc(DIMS, pad_dims, PHS1_FLAG, k_pad, im_pad2); md_free(im_pad2); //--- Consider only center region --- long kc_dims[DIMS]; md_copy_dims(DIMS, kc_dims, pad_dims); kc_dims[PHS1_DIM] = c_region; complex float* kc = md_alloc(DIMS, kc_dims, CFL_SIZE); long pos[DIMS] = { 0 }; pos[PHS1_DIM] = pad_dims[PHS1_DIM] / 2 - (c_region / 2); md_copy_block(DIMS, pos, kc_dims, kc, pad_dims, k_pad, CFL_SIZE); md_free(k_pad); //--- Calculate intersections --- unsigned int Nint = N * no_intersec_sp; // Number of intersection points long idx[2][Nint]; float dist[2][Nint]; complex float S[3][1] = { { 0 } }; calc_intersections(Nint, N, no_intersec_sp, dist, idx, angles, kc_dims, kc, c_region); calc_S(Nint, N, S, angles, dist, idx); check_intersections(Nint, N, S, angles, idx, c_region); bart_printf("%f:%f:%f\n\n", creal(S[0][0]) / pad_factor, creal(S[1][0]) / pad_factor, creal(S[2][0]) / pad_factor); md_free(kc); } unmap_cfl(DIMS, full_dims, full_in); unmap_cfl(DIMS, tdims, traj); md_free(in); return 0; } bart-0.5.00/src/estdims.c000066400000000000000000000021541353046746100151420ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Frank Ong */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" #include "noncart/nufft.h" #define FFT_DIMS (MD_BIT(0)|MD_BIT(1)|MD_BIT(2)) static const char usage_str[] = ""; static const char help_str[] = "Estimate image dimension from non-Cartesian trajectory.\n" "Assume trajectory scaled to -DIM/2 to DIM/2 (ie dk=1/FOV=1)\n"; int main_estdims(int argc, char* argv[]) { mini_cmdline(&argc, argv, 1, usage_str, help_str); num_init(); int N = 16; long traj_dims[N]; complex float* traj = load_cfl(argv[1], N, traj_dims); long im_dims[N]; estimate_im_dims(N, FFT_DIMS, im_dims, traj_dims, traj); bart_printf("%ld %ld %ld\n", im_dims[0], im_dims[1], im_dims[2]); unmap_cfl(N, traj_dims, traj); return 0; } bart-0.5.00/src/estshift.c000066400000000000000000000022761353046746100153300ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include #include "num/multind.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/subpixel.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "flags "; static const char help_str[] = "Estimate sub-pixel shift."; int main_estshift(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); unsigned int flags = atoi(argv[1]); long dims1[DIMS]; long dims2[DIMS]; const complex float* in1 = load_cfl(argv[2], DIMS, dims1); const complex float* in2 = load_cfl(argv[3], DIMS, dims2); assert(md_check_compat(DIMS, ~0u, dims1, dims2)); float shifts[DIMS]; est_subpixel_shift(DIMS, shifts, dims1, flags, in1, in2); bart_printf("Shifts:"); for (unsigned int i = 0; i < DIMS; i++) { if (!MD_IS_SET(flags, i)) continue; bart_printf("\t%f", shifts[i]); } bart_printf("\n"); unmap_cfl(DIMS, dims1, in1); unmap_cfl(DIMS, dims2, in2); return 0; } bart-0.5.00/src/estvar.c000066400000000000000000000033071353046746100147770ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Siddharth Iyer * 2015-2016 Martin Uecker */ #include #include #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "num/flpmath.h" #include "num/multind.h" #include "num/init.h" #include "misc/debug.h" #include "calib/estvar.h" static const char usage_str[] = ""; static const char help_str[] = "Estimate the noise variance assuming white Gaussian noise."; int main_estvar(int argc, char* argv[]) { long calsize_dims[3] = { 24, 24, 24}; long kernel_dims[3] = { 6, 6, 6}; const struct opt_s opts[] = { OPT_VEC3('k', &kernel_dims, "ksize", "kernel size"), OPT_VEC3('K', &kernel_dims, "", "()"), OPT_VEC3('r', &calsize_dims, "cal_size", "Limits the size of the calibration region."), OPT_VEC3('R', &calsize_dims, "", "()"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); int N = DIMS; long kspace_dims[N]; complex float* kspace = load_cfl(argv[1], N, kspace_dims); for (int idx = 0; idx < 3; idx++) { kernel_dims[idx] = (kspace_dims[idx] == 1) ? 1 : kernel_dims[idx]; calsize_dims[idx] = (kspace_dims[idx] == 1) ? 1 : calsize_dims[idx]; } float variance = estvar_kspace(N, kernel_dims, calsize_dims, kspace_dims, kspace); unmap_cfl(N, kspace_dims, kspace); bart_printf("Estimated noise variance: %f\n", variance); return 0; } bart-0.5.00/src/extract.c000066400000000000000000000033171353046746100151460ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "dim1 start1 end1 ... dimn startn endn "; static const char help_str[] = "Extracts a sub-array along dims from index start to (not including) end.\n"; int main_extract(int argc, char* argv[]) { const struct opt_s opts[] = {}; cmdline(&argc, argv, 5, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long in_dims[DIMS]; long out_dims[DIMS]; complex float* in_data = load_cfl(argv[argc - 2], DIMS, in_dims); md_copy_dims(DIMS, out_dims, in_dims); int count = argc - 3; assert((count > 0) && (count % 3 == 0)); long pos2[DIMS] = { [0 ... DIMS - 1] = 0 }; for (int i = 0; i < count; i += 3) { int dim = atoi(argv[i + 1]); int start = atoi(argv[i + 2]); int end = atoi(argv[i + 3]); assert((0 <= dim) && (dim < DIMS)); assert(start >= 0); assert(start < end); assert(end <= in_dims[dim]); out_dims[dim] = end - start; pos2[dim] = start; } complex float* out_data = create_cfl(argv[argc - 1], DIMS, out_dims); md_copy_block(DIMS, pos2, out_dims, out_data, in_dims, in_data, CFL_SIZE); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); return 0; } bart-0.5.00/src/fakeksp.c000066400000000000000000000050751353046746100151230ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "sense/recon.h" #include "sense/optcom.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "misc/debug.h" static const char usage_str[] = " "; static const char help_str[] = "Recreate k-space from image and sensitivities."; int main_fakeksp(int argc, char* argv[]) { bool rplksp = false; const struct opt_s opts[] = { OPT_SET('r', &rplksp, "replace measured samples with original values"), }; cmdline(&argc, argv, 4, 4, usage_str, help_str, ARRAY_SIZE(opts), opts); const int N = DIMS; long ksp_dims[N]; long dims[N]; long img_dims[N]; complex float* kspace_data = load_cfl(argv[2], N, ksp_dims); complex float* sens_maps = load_cfl(argv[3], N, dims); complex float* image = load_cfl(argv[1], N, img_dims); for (int i = 0; i < 4; i++) if (ksp_dims[i] != dims[i]) error("Dimensions of kspace and sensitivities do not match!\n"); assert(1 == ksp_dims[MAPS_DIM]); assert(1 == img_dims[COIL_DIM]); assert(img_dims[MAPS_DIM] == dims[MAPS_DIM]); num_init(); long dims1[N]; md_select_dims(N, ~(COIL_FLAG|MAPS_FLAG), dims1, dims); long dims2[N]; md_copy_dims(DIMS, dims2, img_dims); dims2[COIL_DIM] = dims[COIL_DIM]; dims2[MAPS_DIM] = dims[MAPS_DIM]; #if 0 float scaling = estimate_scaling(ksp_dims, NULL, kspace_data); printf("Scaling: %f\n", scaling); md_zsmul(N, ksp_dims, kspace_data, kspace_data, 1. / scaling); #endif complex float* out = create_cfl(argv[4], N, ksp_dims); fftmod(N, ksp_dims, FFT_FLAGS, kspace_data, kspace_data); fftmod(N, dims, FFT_FLAGS, sens_maps, sens_maps); if (rplksp) { debug_printf(DP_INFO, "Replace kspace\n"); replace_kspace(dims2, out, kspace_data, sens_maps, image); // this overwrites kspace_data (FIXME: think not!) } else { debug_printf(DP_INFO, "Simulate kspace\n"); fake_kspace(dims2, out, sens_maps, image); } #if 0 md_zsmul(N, ksp_dims, out, out, scaling); #endif fftmod(N, ksp_dims, FFT_FLAGS, out, out); unmap_cfl(N, ksp_dims, kspace_data); unmap_cfl(N, dims, sens_maps); unmap_cfl(N, img_dims, image); unmap_cfl(N, ksp_dims, out); return 0; } bart-0.5.00/src/fft.c000066400000000000000000000027601353046746100142540ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/fft.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/opts.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Performs a fast Fourier transform (FFT) along selected dimensions."; int main_fft(int argc, char* argv[]) { bool unitary = false; bool inv = false; bool center = true; const struct opt_s opts[] = { OPT_SET('u', &unitary, "unitary"), OPT_SET('i', &inv, "inverse"), OPT_CLEAR('n', ¢er, "un-centered"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long dims[DIMS]; complex float* idata = load_cfl(argv[2], DIMS, dims); complex float* data = create_cfl(argv[3], DIMS, dims); unsigned long flags = labs(atol(argv[1])); md_copy(DIMS, dims, data, idata, sizeof(complex float)); unmap_cfl(DIMS, dims, idata); if (unitary) fftscale(DIMS, dims, flags, data, data); (inv ? (center ? ifftc : ifft) : (center ? fftc : fft))(DIMS, dims, flags, data, data); unmap_cfl(DIMS, dims, data); return 0; } bart-0.5.00/src/fftmod.c000066400000000000000000000024601353046746100147510ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2016 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/fft.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Apply 1 -1 modulation along dimensions selected by the {bitmask}.\n"; int main_fftmod(int argc, char* argv[]) { bool inv = false; const struct opt_s opts[] = { OPT_SET('b', &inv, "(deprecated)"), OPT_SET('i', &inv, "\tinverse"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned long flags = labs(atol(argv[1])); int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); (inv ? ifftmod : fftmod)(N, dims, flags, odata, idata); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/fftrot.c000066400000000000000000000045001353046746100147730ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Martin Uecker */ #include #include #include #include #include #include "num/init.h" #include "num/fft.h" #include "num/flpmath.h" #include "num/multind.h" #include "misc/opts.h" #include "misc/misc.h" #include "misc/mmio.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "dim1 dim2 theta "; static const char help_str[] = "Performs a rotation using Fourier transform (FFT) along selected dimensions."; int main_fftrot(int argc, char* argv[]) { const struct opt_s opts[] = { }; cmdline(&argc, argv, 5, 5, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[4], N, dims); complex float* odata = create_cfl(argv[5], N, dims); int dim1 = atoi(argv[1]); int dim2 = atoi(argv[2]); assert(dim1 != dim2); if (dim1 > dim2) { int tmp = dim1; dim1 = dim2; dim2 = tmp; } float theta = atof(argv[3]); float alpha = -tanf(theta / 2.); float beta = sinf(theta); long flags = (1 << dim1) | (1 << dim2); long phdims[N]; md_select_dims(N, flags, phdims, dims); complex float* phx = md_alloc(N, phdims, CFL_SIZE); complex float* phy = md_alloc(N, phdims, CFL_SIZE); int X = phdims[dim1]; int Y = phdims[dim2]; for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { phx[i + X * j] = cexpf(+2.i * M_PI * ((j - Y / 2.) * alpha * (i - X / 2.) / (float)(X))); phy[i + X * j] = cexpf(-2.i * M_PI * ((j - Y / 2.) * beta * (i - X / 2.) / (float)(Y))); } } long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); long phstrs[N]; md_calc_strides(N, phstrs, phdims, CFL_SIZE); fftuc(N, dims, (1u << dim1), odata, idata); md_zmul2(N, dims, strs, odata, strs, odata, phstrs, phx); ifftuc(N, dims, flags, odata, odata); md_zmul2(N, dims, strs, odata, strs, odata, phstrs, phy); fftuc(N, dims, flags, odata, odata); md_zmul2(N, dims, strs, odata, strs, odata, phstrs, phx); ifftuc(N, dims, (1u << dim1), odata, odata); md_free(phx); md_free(phy); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/fftshift.c000066400000000000000000000021451353046746100153070ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2015 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/fft.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Apply fftshift along dimensions selected by the {bitmask}.\n"; int main_fftshift(int argc, char* argv[]) { bool b = mini_cmdline_bool(&argc, argv, 'b', 3, usage_str, help_str); num_init(); unsigned long flags = labs(atol(argv[1])); int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); (b ? ifftshift : fftshift)(N, dims, flags, odata, idata); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/filter.c000066400000000000000000000034411353046746100147570ustar00rootroot00000000000000/* Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Martin Uecker */ #include #include #include "num/multind.h" #include "num/casorati.h" #include "num/filter.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "misc/debug.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = " "; static const char help_str[] = "Apply filter.\n"; int main_filter(int argc, char* argv[]) { int len = -1; int dim = -1; const struct opt_s opts[] = { OPT_INT('m', &dim, "dim", "median filter along dimension dim"), OPT_INT('l', &len, "len", "length of filter"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long in_dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, in_dims); assert(dim >= 0); assert(dim < DIMS); assert(len > 0); assert(len <= in_dims[dim]); long tmp_dims[DIMS + 1]; md_copy_dims(DIMS, tmp_dims, in_dims); tmp_dims[DIMS] = 1; long tmp_strs[DIMS + 1]; md_calc_strides(DIMS, tmp_strs, tmp_dims, CFL_SIZE); tmp_dims[dim] = in_dims[dim] - len + 1; long tmp2_strs[DIMS + 1]; md_calc_strides(DIMS + 1, tmp2_strs, tmp_dims, CFL_SIZE); tmp_dims[DIMS] = len; tmp_strs[DIMS] = tmp_strs[dim]; long out_dims[DIMS]; md_copy_dims(DIMS, out_dims, tmp_dims); complex float* out_data = create_cfl(argv[2], DIMS, out_dims); md_medianz2(DIMS + 1, DIMS, tmp_dims, tmp2_strs, out_data, tmp_strs, in_data); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); return 0; } bart-0.5.00/src/flatten.c000066400000000000000000000020641353046746100151270ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jon Tamir */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Flatten array to one dimension.\n"; int main_flatten(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long idims[DIMS]; complex float* idata = load_cfl(argv[1], DIMS, idims); long odims[DIMS] = MD_INIT_ARRAY(DIMS, 1); odims[0] = md_calc_size(DIMS, idims); complex float* odata = create_cfl(argv[2], DIMS, odims); md_copy(DIMS, idims, odata, idata, CFL_SIZE); unmap_cfl(DIMS, idims, idata); unmap_cfl(DIMS, odims, odata); return 0; } bart-0.5.00/src/flip.c000066400000000000000000000020541353046746100144230ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Flip (reverse) dimensions specified by the {bitmask}.\n"; int main_flip(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); unsigned long flags = atoi(argv[1]); md_flip(N, dims, flags, odata, idata, sizeof(complex float)); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/fmac.c000066400000000000000000000042471353046746100144050ustar00rootroot00000000000000/* Copyright 2013, 2016. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2015 Martin Uecker * 2016 Jon Tamir */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " [] "; static const char help_str[] = "Multiply and and accumulate in .\n" "If is not specified, assume all-ones."; int main_fmac(int argc, char* argv[]) { bool clear = true; bool conj = false; long squash = 0; const struct opt_s opts[] = { OPT_CLEAR('A', &clear, "add to existing output (instead of overwriting)"), OPT_SET('C', &conj, "conjugate input2"), OPT_LONG('s', &squash, "b", "squash dimensions selected by bitmask b"), }; cmdline(&argc, argv, 2, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); int num_args = argc - 1; num_init(); int N = DIMS; long dims1[N]; long dims2[N]; complex float* data1 = load_cfl(argv[1], N, dims1); complex float* data2 = NULL; if (3 == num_args) data2 = load_cfl(argv[2], N, dims2); else { md_singleton_dims(N, dims2); data2 = md_alloc(N, dims2, CFL_SIZE); md_zfill(N, dims2, data2, 1.); } long dims[N]; md_merge_dims(N, dims, dims1, dims2); long dimso[N]; md_select_dims(N, ~squash, dimso, dims); complex float* out = create_cfl((3 == num_args) ? argv[3] : argv[2], N, dimso); if (clear) { md_clear(N, dimso, out, CFL_SIZE); } long str1[N]; long str2[N]; long stro[N]; md_calc_strides(N, str1, dims1, CFL_SIZE); md_calc_strides(N, str2, dims2, CFL_SIZE); md_calc_strides(N, stro, dimso, CFL_SIZE); (conj ? md_zfmacc2 : md_zfmac2)(N, dims, stro, out, str1, data1, str2, data2); unmap_cfl(N, dims1, data1); unmap_cfl(N, dimso, out); if (3 == num_args) unmap_cfl(N, dims2, data2); else md_free(data2); return 0; } bart-0.5.00/src/grecon/000077500000000000000000000000001353046746100146015ustar00rootroot00000000000000bart-0.5.00/src/grecon/italgo.c000066400000000000000000000111451353046746100162260ustar00rootroot00000000000000/* Copyright 2016-2018. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016-2018 Martin Uecker * 2016-2018 Jon Tamir * */ #include #include #include #include "misc/debug.h" #include "misc/types.h" #include "misc/misc.h" #include "iter/iter2.h" #include "iter/iter.h" #include "grecon/optreg.h" // enum algo_t #include "italgo.h" enum algo_t italgo_choose(int nr_penalties, const struct reg_s regs[nr_penalties]) { enum algo_t algo = ALGO_CG; for (int i = 0; i < nr_penalties; i++) { switch (regs[i].xform) { case L2IMG: break; case NIHTWAV: case NIHTIM: algo = ALGO_NIHT; break; case TV: case IMAGL1: case IMAGL2: algo = ALGO_ADMM; break; default: if (0 == i) algo = ALGO_FISTA; else algo = ALGO_ADMM; break; } } return algo; } struct iter italgo_config(enum algo_t algo, int nr_penalties, const struct reg_s* regs, unsigned int maxiter, float step, bool hogwild, bool fast, const struct admm_conf admm, float scaling, bool warm_start) { italgo_fun2_t italgo = NULL; iter_conf* iconf = NULL; switch (algo) { case ALGO_DEFAULT: assert(0); case ALGO_CG: { debug_printf(DP_INFO, "conjugate gradients\n"); assert((0 == nr_penalties) || ((1 == nr_penalties) && (L2IMG == regs[0].xform))); PTR_ALLOC(struct iter_conjgrad_conf, cgconf); *cgconf = iter_conjgrad_defaults; cgconf->maxiter = maxiter; cgconf->l2lambda = (0 == nr_penalties) ? 0. : regs[0].lambda; PTR_ALLOC(struct iter_call_s, iter2_data); SET_TYPEID(iter_call_s, iter2_data); iter2_data->fun = iter_conjgrad; iter2_data->_conf = CAST_UP(PTR_PASS(cgconf)); italgo = iter2_call_iter; iconf = CAST_UP(PTR_PASS(iter2_data)); break; } case ALGO_IST: { debug_printf(DP_INFO, "IST\n"); assert(1 == nr_penalties); PTR_ALLOC(struct iter_ist_conf, isconf); *isconf = iter_ist_defaults; isconf->maxiter = maxiter; isconf->step = step; isconf->hogwild = hogwild; PTR_ALLOC(struct iter_call_s, iter2_ist_data); SET_TYPEID(iter_call_s, iter2_ist_data); iter2_ist_data->fun = iter_ist; iter2_ist_data->_conf = CAST_UP(PTR_PASS(isconf)); italgo = iter2_call_iter; iconf = CAST_UP(PTR_PASS(iter2_ist_data)); break; } case ALGO_ADMM: { debug_printf(DP_INFO, "ADMM\n"); PTR_ALLOC(struct iter_admm_conf, mmconf); *mmconf = iter_admm_defaults; mmconf->maxiter = maxiter; mmconf->maxitercg = admm.maxitercg; mmconf->rho = admm.rho; mmconf->hogwild = hogwild; mmconf->fast = fast; mmconf->dynamic_rho = admm.dynamic_rho; mmconf->dynamic_tau = admm.dynamic_tau; mmconf->relative_norm = admm.relative_norm; mmconf->ABSTOL = 0.; mmconf->RELTOL = 0.; mmconf->do_warmstart = warm_start; italgo = iter2_admm; iconf = CAST_UP(PTR_PASS(mmconf)); break; } case ALGO_PRIDU: { debug_printf(DP_INFO, "Primal Dual\n"); assert(2 == nr_penalties); PTR_ALLOC(struct iter_chambolle_pock_conf, pdconf); *pdconf = iter_chambolle_pock_defaults; pdconf->maxiter = maxiter; pdconf->sigma = sqrtf(step); pdconf->tau = sqrtf(step); pdconf->sigma *= scaling; pdconf->tau /= scaling; pdconf->theta = 1.; pdconf->decay = (hogwild ? .95 : 1.); pdconf->tol = 1.E-4; italgo = iter2_chambolle_pock; iconf = CAST_UP(PTR_PASS(pdconf)); break; } case ALGO_FISTA: { debug_printf(DP_INFO, "FISTA\n"); assert(1 == nr_penalties); PTR_ALLOC(struct iter_fista_conf, fsconf); *fsconf = iter_fista_defaults; fsconf->maxiter = maxiter; fsconf->step = step; fsconf->hogwild = hogwild; PTR_ALLOC(struct iter_call_s, iter2_fista_data); SET_TYPEID(iter_call_s, iter2_fista_data); iter2_fista_data->fun = iter_fista; iter2_fista_data->_conf = CAST_UP(PTR_PASS(fsconf)); italgo = iter2_call_iter; iconf = CAST_UP(PTR_PASS(iter2_fista_data)); break; } case ALGO_NIHT: { debug_printf(DP_INFO, "NIHT\n"); PTR_ALLOC(struct iter_niht_conf, ihconf); *ihconf = iter_niht_defaults; ihconf->maxiter = maxiter; ihconf->do_warmstart = warm_start; italgo = iter2_niht; iconf = CAST_UP(PTR_PASS(ihconf)); break; } default: assert(0); } return (struct iter){ italgo, iconf }; } void italgo_config_free(struct iter it) { if (iter2_call_iter == it.italgo) { auto id = CAST_DOWN(iter_call_s, it.iconf); xfree(id->_conf); } xfree(it.iconf); } bart-0.5.00/src/grecon/italgo.h000066400000000000000000000012321353046746100162270ustar00rootroot00000000000000 enum algo_t { ALGO_DEFAULT, ALGO_CG, ALGO_IST, ALGO_FISTA, ALGO_ADMM, ALGO_NIHT, ALGO_PRIDU }; struct admm_conf { bool dynamic_rho; bool dynamic_tau; bool relative_norm; float rho; unsigned int maxitercg; }; struct iter { italgo_fun2_t italgo; iter_conf* iconf; }; struct reg_s; enum algo_t; extern enum algo_t italgo_choose(int nr_penalties, const struct reg_s regs[nr_penalties]); extern struct iter italgo_config(enum algo_t algo, int nr_penalties, const struct reg_s* regs, unsigned int maxiter, float step, bool hogwild, bool fast, const struct admm_conf admm, float scaling, bool warm_start); extern void italgo_config_free(struct iter it); bart-0.5.00/src/grecon/optreg.c000066400000000000000000000335451353046746100162570ustar00rootroot00000000000000/* Copyright 2015-2017. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015-2018 Martin Uecker * 2015-2016 Frank Ong * 2015-2017 Jon Tamir * */ #include #include #include #include #include #include "num/multind.h" #include "num/iovec.h" #include "num/ops_p.h" #include "num/ops.h" #include "iter/prox.h" #include "iter/thresh.h" #include "linops/linop.h" #include "linops/someops.h" #include "linops/grad.h" #include "linops/sum.h" #include "linops/waveop.h" #include "wavelet/wavthresh.h" #include "lowrank/lrthresh.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/opts.h" #include "misc/debug.h" #include "optreg.h" #define CFL_SIZE sizeof(complex float) void help_reg(void) { printf( "Generalized regularization options (experimental)\n\n" "-R :A:B:C\t is regularization type (single letter),\n" "\t\tA is transform flags, B is joint threshold flags,\n" "\t\tand C is regularization value. Specify any number\n" "\t\tof regularization terms.\n\n" "-R Q:C \tl2-norm in image domain\n" "-R I:B:C \tl1-norm in image domain\n" "-R W:A:B:C\tl1-wavelet\n" "-R N:A:B:C\tNormalized Iterative Hard Thresholding (NIHT), image domain\n" "\t\tC is an integer percentage, i.e. from 0-100\n" "-R H:A:B:C\tNIHT, wavelet domain\n" "-R F:A:B:C\tl1-Fourier\n" "-R T:A:B:C\ttotal variation\n" "-R T:7:0:.01\t3D isotropic total variation with 0.01 regularization.\n" "-R L:7:7:.02\tLocally low rank with spatial decimation and 0.02 regularization.\n" "-R M:7:7:.03\tMulti-scale low rank with spatial decimation and 0.03 regularization.\n" ); } bool opt_reg(void* ptr, char c, const char* optarg) { struct opt_reg_s* p = ptr; struct reg_s* regs = p->regs; const int r = p->r; const float lambda = p->lambda; assert(r < NUM_REGS); char rt[5]; switch (c) { case 'R': { // first get transform type int ret = sscanf(optarg, "%4[^:]", rt); assert(1 == ret); // next switch based on transform type if (strcmp(rt, "W") == 0) { regs[r].xform = L1WAV; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "H") == 0) { regs[r].xform = NIHTWAV; int ret = sscanf(optarg, "%*[^:]:%d:%d:%d", ®s[r].xflags, ®s[r].jflags, ®s[r].k); assert(3 == ret); } else if (strcmp(rt, "N") == 0) { regs[r].xform = NIHTIM; int ret = sscanf(optarg, "%*[^:]:%d:%d:%d", ®s[r].xflags, ®s[r].jflags, ®s[r].k); assert(3 == ret); } else if (strcmp(rt, "L") == 0) { regs[r].xform = LLR; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "M") == 0) { // FIXME: here an explanation is missing regs[r].xform = regs[0].xform; regs[r].xflags = regs[0].xflags; regs[r].jflags = regs[0].jflags; regs[r].lambda = regs[0].lambda; regs[0].xform = MLR; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[0].xflags, ®s[0].jflags, ®s[0].lambda); assert(3 == ret); } else if (strcmp(rt, "T") == 0) { regs[r].xform = TV; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "P") == 0) { regs[r].xform = LAPLACE; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "R1") == 0) { regs[r].xform = IMAGL1; int ret = sscanf(optarg, "%*[^:]:%d:%f", ®s[r].jflags, ®s[r].lambda); assert(2 == ret); regs[r].xflags = 0u; } else if (strcmp(rt, "R2") == 0) { regs[r].xform = IMAGL2; int ret = sscanf(optarg, "%*[^:]:%d:%f", ®s[r].jflags, ®s[r].lambda); assert(2 == ret); regs[r].xflags = 0u; } else if (strcmp(rt, "I") == 0) { regs[r].xform = L1IMG; int ret = sscanf(optarg, "%*[^:]:%d:%f", ®s[r].jflags, ®s[r].lambda); assert(2 == ret); regs[r].xflags = 0u; } else if (strcmp(rt, "S") == 0) { regs[r].xform = POS; regs[r].lambda = 0u; regs[r].xflags = 0u; regs[r].jflags = 0u; } else if (strcmp(rt, "Q") == 0) { regs[r].xform = L2IMG; int ret = sscanf(optarg, "%*[^:]:%f", ®s[r].lambda); assert(1 == ret); regs[r].xflags = 0u; regs[r].jflags = 0u; } else if (strcmp(rt, "F") == 0) { regs[r].xform = FTL1; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "h") == 0) { help_reg(); exit(0); } else { error("Unrecognized regularization type: \"%s\" (-Rh for help).\n", rt); } p->r++; break; } case 'l': assert(r < NUM_REGS); regs[r].lambda = lambda; regs[r].xflags = 0u; regs[r].jflags = 0u; if (0 == strcmp("1", optarg)) { regs[r].xform = L1WAV; regs[r].xflags = 7u; } else if (0 == strcmp("2", optarg)) { regs[r].xform = L2IMG; } else { error("Unknown regularization type.\n"); } p->lambda = -1.; p->r++; break; } return false; } bool opt_reg_init(struct opt_reg_s* ropts) { ropts->r = 0; ropts->lambda = -1; ropts->k = 0; return false; } void opt_bpursuit_configure(struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS], const struct linop_s* model_op, const complex float* data, const float eps) { int nr_penalties = ropts->r; assert(NUM_REGS > nr_penalties); const struct iovec_s* iov = linop_codomain(model_op); prox_ops[nr_penalties] = prox_l2ball_create(iov->N, iov->dims, eps, data); trafos[nr_penalties] = linop_clone(model_op); ropts->r++; } void opt_reg_configure(unsigned int N, const long img_dims[N], struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS], unsigned int llr_blk, unsigned int shift_mode, bool use_gpu) { float lambda = ropts->lambda; bool randshift = shift_mode == 1; bool overlapping_blocks = shift_mode == 2; if (-1. == lambda) lambda = 0.; // if no penalities specified but regularization // parameter is given, add a l2 penalty struct reg_s* regs = ropts->regs; if ((0 == ropts->r) && (lambda > 0.)) { regs[0].xform = L2IMG; regs[0].xflags = 0u; regs[0].jflags = 0u; regs[0].lambda = lambda; ropts->r = 1; } int nr_penalties = ropts->r; long blkdims[MAX_LEV][DIMS]; int levels; for (int nr = 0; nr < nr_penalties; nr++) { // fix up regularization parameter if (-1. == regs[nr].lambda) regs[nr].lambda = lambda; switch (regs[nr].xform) { case L1WAV: { debug_printf(DP_INFO, "l1-wavelet regularization: %f\n", regs[nr].lambda); long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(img_dims[0], 16); minsize[1] = MIN(img_dims[1], 16); minsize[2] = MIN(img_dims[2], 16); unsigned int wflags = 0; for (unsigned int i = 0; i < DIMS; i++) { if ((1 < img_dims[i]) && MD_IS_SET(regs[nr].xflags, i)) { wflags = MD_SET(wflags, i); minsize[i] = MIN(img_dims[i], 16); } } trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = prox_wavelet_thresh_create(DIMS, img_dims, wflags, regs[nr].jflags, minsize, regs[nr].lambda, randshift); break; } case NIHTWAV: { debug_printf(DP_INFO, "NIHT with wavelets regularization: k = %d%% of total elements in each wavelet transform\n", regs[nr].k); if (use_gpu) error("GPU operation is not currently implemented for NIHT.\n"); long img_strs[N]; md_calc_strides(N, img_strs, img_dims, CFL_SIZE); long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(img_dims[0], 16); minsize[1] = MIN(img_dims[1], 16); minsize[2] = MIN(img_dims[2], 16); unsigned int wflags = 0; unsigned int wxdim = 0; for (unsigned int i = 0; i < DIMS; i++) { if ((1 < img_dims[i]) && MD_IS_SET(regs[nr].xflags, i)) { wflags = MD_SET(wflags, i); minsize[i] = MIN(img_dims[i], 16); wxdim += 1; } } trafos[nr] = linop_wavelet_create(N, wflags, img_dims, img_strs, minsize, randshift); long wav_dims[DIMS]; md_copy_dims(DIMS, wav_dims, linop_codomain(trafos[nr])->dims); unsigned int K = (md_calc_size(wxdim, wav_dims) / 100) * regs[nr].k; debug_printf(DP_DEBUG3, "\nK = %d elements will be thresholded per wavelet transform\n", K); debug_printf(DP_DEBUG3, "Total wavelet dimensions: \n["); for (unsigned int i = 0; i < DIMS; i++) debug_printf(DP_DEBUG3,"%d ", wav_dims[i]); debug_printf(DP_DEBUG3, "]\n"); prox_ops[nr] = prox_niht_thresh_create(N, wav_dims, K, regs[nr].jflags); break; } case NIHTIM: { debug_printf(DP_INFO, "NIHT regularization in the image domain: k = %d%% of total elements in image vector\n", regs[nr].k); if (use_gpu) error("GPU operation is not currently implemented for NIHT.\n"); long thresh_dims[N]; md_select_dims(N, regs[nr].xflags, thresh_dims, img_dims); unsigned int K = (md_calc_size(N, thresh_dims) / 100) * regs[nr].k; debug_printf(DP_INFO, "k = %d%%, actual K = %d\n", regs[nr].k, K); trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = prox_niht_thresh_create(N, img_dims, K, regs[nr].jflags); debug_printf(DP_INFO, "NIHTIM initialization complete\n"); break; } case TV: debug_printf(DP_INFO, "TV regularization: %f\n", regs[nr].lambda); trafos[nr] = linop_grad_create(DIMS, img_dims, DIMS, regs[nr].xflags); prox_ops[nr] = prox_thresh_create(DIMS + 1, linop_codomain(trafos[nr])->dims, regs[nr].lambda, regs[nr].jflags | MD_BIT(DIMS)); break; case LAPLACE: debug_printf(DP_INFO, "L1-Laplace regularization: %f\n", regs[nr].lambda); long krn_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; for (unsigned int i = 0; i < DIMS; i++) if (MD_IS_SET(regs[nr].xflags, i)) krn_dims[i] = 3; complex float krn[] = { // laplace filter -1., -2., -1., -2., 12., -2., -1., -2., -1., }; assert(9 == md_calc_size(DIMS, krn_dims)); trafos[nr] = linop_conv_create(DIMS, regs[nr].xflags, CONV_TRUNCATED, CONV_SYMMETRIC, img_dims, img_dims, krn_dims, krn); prox_ops[nr] = prox_thresh_create(DIMS, linop_codomain(trafos[nr])->dims, regs[nr].lambda, regs[nr].jflags); break; case LLR: debug_printf(DP_INFO, "lowrank regularization: %f\n", regs[nr].lambda); if (use_gpu) error("GPU operation is not currently implemented for lowrank regularization.\n"); // add locally lowrank penalty levels = llr_blkdims(blkdims, regs[nr].jflags, img_dims, llr_blk); assert(1 == levels); assert(levels == img_dims[LEVEL_DIM]); for(int l = 0; l < levels; l++) #if 0 blkdims[l][MAPS_DIM] = img_dims[MAPS_DIM]; #else blkdims[l][MAPS_DIM] = 1; #endif int remove_mean = 0; trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = lrthresh_create(img_dims, randshift, regs[nr].xflags, (const long (*)[DIMS])blkdims, regs[nr].lambda, false, remove_mean, overlapping_blocks); break; case MLR: #if 0 // FIXME: multiscale low rank changes the output image dimensions // and requires the forward linear operator. This should be decoupled... debug_printf(DP_INFO, "multi-scale lowrank regularization: %f\n", regs[nr].lambda); levels = multilr_blkdims(blkdims, regs[nr].jflags, img_dims, 8, 1); img_dims[LEVEL_DIM] = levels; max_dims[LEVEL_DIM] = levels; for(int l = 0; l < levels; l++) blkdims[l][MAPS_DIM] = 1; trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = lrthresh_create(img_dims, randshift, regs[nr].xflags, (const long (*)[DIMS])blkdims, regs[nr].lambda, false, 0, use_gpu); const struct linop_s* decom_op = sum_create( img_dims, use_gpu ); const struct linop_s* tmp_op = forward_op; forward_op = linop_chain(decom_op, forward_op); linop_free(decom_op); linop_free(tmp_op); #else error("multi-scale lowrank regularization not supported.\n"); #endif break; case IMAGL1: debug_printf(DP_INFO, "l1 regularization of imaginary part: %f\n", regs[nr].lambda); trafos[nr] = linop_rdiag_create(DIMS, img_dims, 0, &(complex float){ 1.i }); prox_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags); break; case IMAGL2: debug_printf(DP_INFO, "l2 regularization of imaginary part: %f\n", regs[nr].lambda); trafos[nr] = linop_rdiag_create(DIMS, img_dims, 0, &(complex float){ 1.i }); prox_ops[nr] = prox_leastsquares_create(DIMS, img_dims, regs[nr].lambda, NULL); break; case L1IMG: debug_printf(DP_INFO, "l1 regularization: %f\n", regs[nr].lambda); trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags); break; case POS: debug_printf(DP_INFO, "non-negative constraint\n"); trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = prox_nonneg_create(DIMS, img_dims); break; case L2IMG: debug_printf(DP_INFO, "l2 regularization: %f\n", regs[nr].lambda); trafos[nr] = linop_identity_create(DIMS, img_dims); prox_ops[nr] = prox_leastsquares_create(DIMS, img_dims, regs[nr].lambda, NULL); break; case FTL1: debug_printf(DP_INFO, "l1 regularization of Fourier transform: %f\n", regs[nr].lambda); trafos[nr] = linop_fft_create(DIMS, img_dims, regs[nr].xflags); prox_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags); break; } } } void opt_reg_free(struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS]) { int nr_penalties = ropts->r; for (int nr = 0; nr < nr_penalties; nr++) { operator_p_free(prox_ops[nr]); linop_free(trafos[nr]); } } bart-0.5.00/src/grecon/optreg.h000066400000000000000000000026711353046746100162600ustar00rootroot00000000000000/* Copyright 2014-2017. The Regents of the University of California. * Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __OPTREG_H #define __OPTREG_H #include "misc/cppwrap.h" #define NUM_REGS 10 struct operator_p_s; struct linop_s; struct reg_s { enum { L1WAV, NIHTWAV, NIHTIM, TV, LLR, MLR, IMAGL1, IMAGL2, L1IMG, L2IMG, FTL1, LAPLACE, POS } xform; unsigned int xflags; unsigned int jflags; float lambda; unsigned int k; }; struct opt_reg_s { float lambda; struct reg_s regs[NUM_REGS]; unsigned int r; unsigned int k; }; extern _Bool opt_reg_init(struct opt_reg_s* ropts); extern void opt_bpursuit_configure(struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS], const struct linop_s* model_op, const _Complex float* data, const float eps); extern void opt_reg_configure(unsigned int N, const long img_dims[__VLA(N)], struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS], unsigned int llr_blk, unsigned int shift_mode, _Bool use_gpu); extern void opt_reg_free(struct opt_reg_s* ropts, const struct operator_p_s* prox_ops[NUM_REGS], const struct linop_s* trafos[NUM_REGS]); extern _Bool opt_reg(void* ptr, char c, const char* optarg); extern void help_reg(void); #include "misc/cppwrap.h" #endif bart-0.5.00/src/homodyne.c000066400000000000000000000116361353046746100153210ustar00rootroot00000000000000/* Copyright 2014-2017. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2016 Martin Uecker * 2015, 2017 Jonathan Tamir */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "misc/nested.h" static const char usage_str[] = "dim fraction "; static const char help_str[] = "Perform homodyne reconstruction along dimension dim."; struct wdata { float frac; int pfdim; long wdims[DIMS]; long wstrs[DIMS]; complex float* weights; }; /** * Applies the Homodyne filter. * @param N k-space dimension * @param p k-space position * @param frac is the fraction of acquired k-space * @param alpha is the offset of the ramp, between 0 and 1 * @param clear clear acquired k-space * * The ramp portion is given by 2*(alpha - 1) / (end - start) * (p - end) + alpha * alpha = 0 is a full ramp, alpha = 1 is a horizontal line */ static float homodyne_filter(long N, float frac, float alpha, bool clear, long p) { if (frac <= 0.5) return 1.; float start = N * (1 - frac); float end = N * frac; float ret = clear ? 0. : 1.; if (p < start) ret = 2.; else if (p >= start && p < end) ret = 2 * (alpha - 1) / (end - start) * (p - end) + alpha; return ret; } static complex float* estimate_phase(struct wdata wdata, unsigned int flags, unsigned int N, const long dims[N], const complex float* idata, bool center_fft) { long cdims[N]; md_copy_dims(N, cdims, dims); // cdims[0] = cdims[1] = cdims[2] = 24; cdims[wdata.pfdim] = (wdata.frac - 0.5) * dims[wdata.pfdim]; complex float* center = md_alloc(N, cdims, CFL_SIZE); complex float* phase = md_alloc(N, dims, CFL_SIZE); md_resize_center(N, cdims, center, dims, idata, CFL_SIZE); md_resize_center(N, dims, phase, cdims, center, CFL_SIZE); md_free(center); (center_fft ? ifftuc : ifftu)(N, dims, flags, phase, phase); md_zphsr(N, dims, phase, phase); return phase; } static void homodyne(struct wdata wdata, unsigned int flags, unsigned int N, const long dims[N], const long strs[N], complex float* data, const complex float* idata, const long pstrs[N], const complex float* phase, bool center_fft) { md_zmul2(N, dims, strs, data, strs, idata, wdata.wstrs, wdata.weights); (center_fft ? ifftuc : ifftu)(N, dims, flags, data, data); md_zmulc2(N, dims, strs, data, strs, data, pstrs, phase); md_zreal(N, dims, data, data); } int main_homodyne(int argc, char* argv[]) { bool clear = false; bool image = false; bool center_fft = true; const char* phase_ref = NULL; float alpha = 0.; num_init(); const struct opt_s opts[] = { OPT_FLOAT('r', &alpha, "alpha", "Offset of ramp filter, between 0 and 1. alpha=0 is a full ramp, alpha=1 is a horizontal line"), OPT_SET('I', &image, "Input is in image domain"), OPT_SET('C', &clear, "Clear unacquired portion of kspace"), OPT_STRING('P', &phase_ref, "phase_ref>", "Use as phase reference"), OPT_CLEAR('n', ¢er_fft, "use uncentered ffts"), }; cmdline(&argc, argv, 4, 4, usage_str, help_str, ARRAY_SIZE(opts), opts); const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[3], N, dims); complex float* data = create_cfl(argv[4], N, dims); int pfdim = atoi(argv[1]); float frac = atof(argv[2]); assert((0 <= pfdim) && (pfdim < N)); assert(frac > 0.); if (image) { complex float* ksp_in = md_alloc(N, dims, CFL_SIZE); (center_fft ? fftuc : fftu)(N, dims, FFT_FLAGS, ksp_in, idata); md_copy(N, dims, idata, ksp_in, CFL_SIZE); md_free(ksp_in); } long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); struct wdata wdata; wdata.frac = frac; wdata.pfdim = pfdim; md_select_dims(N, MD_BIT(pfdim), wdata.wdims, dims); md_calc_strides(N, wdata.wstrs, wdata.wdims, CFL_SIZE); wdata.weights = md_alloc(N, wdata.wdims, CFL_SIZE); NESTED(void, comp_weights, (const long pos[])) { wdata.weights[md_calc_offset(DIMS, wdata.wstrs, pos) / CFL_SIZE] = homodyne_filter(wdata.wdims[pfdim], frac, alpha, clear, pos[pfdim]); }; md_loop(N, wdata.wdims, comp_weights); long pstrs[N]; long pdims[N]; complex float* phase = NULL; if (NULL == phase_ref) { phase = estimate_phase(wdata, FFT_FLAGS, N, dims, idata, center_fft); md_copy_dims(N, pdims, dims); } else phase = load_cfl(phase_ref, N, pdims); md_calc_strides(N, pstrs, pdims, CFL_SIZE); homodyne(wdata, FFT_FLAGS, N, dims, strs, data, idata, pstrs, phase, center_fft); md_free(wdata.weights); if (NULL == phase_ref) md_free(phase); else { unmap_cfl(N, pdims, phase); free((void*)phase_ref); } unmap_cfl(N, dims, idata); unmap_cfl(N, dims, data); return 0; } bart-0.5.00/src/index.c000066400000000000000000000020301353046746100145720ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" static const char usage_str[] = "dim size name"; static const char help_str[] = "Create an array counting from 0 to {size-1} in dimensions {dim}.\n"; int main_index(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); int N = atoi(argv[1]); int s = atoi(argv[2]); assert(N >= 0); assert(s >= 0); long dims[N + 1]; for (int i = 0; i < N; i++) dims[i] = 1; dims[N] = s; complex float* x = create_cfl(argv[3], N + 1, dims); for (int i = 0; i < s; i++) x[i] = i; unmap_cfl(N + 1, dims, x); exit(0); } bart-0.5.00/src/invert.c000066400000000000000000000021031353046746100147730ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jon Tamir */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Invert array (1 / ). The output is set to zero in case of divide by zero.\n"; int main_invert(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long dims[DIMS]; complex float* idata = load_cfl(argv[1], DIMS, dims); complex float* odata = create_cfl(argv[2], DIMS, dims); #pragma omp parallel for for (long i = 0; i < md_calc_size(DIMS, dims); i++) odata[i] = idata[i] == 0 ? 0. : 1. / idata[i]; unmap_cfl(DIMS, dims, idata); unmap_cfl(DIMS, dims, odata); return 0; } bart-0.5.00/src/ismrm/000077500000000000000000000000001353046746100144535ustar00rootroot00000000000000bart-0.5.00/src/ismrm/read.c000066400000000000000000000053371353046746100155420ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2016 Martin Uecker */ #include #include #include #include "ismrmrd/ismrmrd.h" #include "ismrmrd/dataset.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "read.h" // FIXME: does not deal correctly with repetitions (and others stuff) int ismrm_read(const char* datafile, long dims[DIMS], complex float* buf) { ISMRMRD_Dataset d; ismrmrd_init_dataset(&d, datafile, "/dataset"); ismrmrd_open_dataset(&d, false); assert(DIMS > 5); unsigned int number_of_acquisitions = ismrmrd_get_number_of_acquisitions(&d); long pos[DIMS]; long channels = -1; long slices = 0; long samples = -1; for (unsigned int i = 0; i < DIMS; i++) pos[i] = 0; long strs[DIMS]; long adc_dims[DIMS]; long adc_strs[DIMS]; if (NULL == buf) { md_singleton_dims(DIMS, dims); } else { md_calc_strides(DIMS, strs, dims, CFL_SIZE); md_select_dims(DIMS, READ_FLAG|COIL_FLAG, adc_dims, dims); md_calc_strides(DIMS, adc_strs, adc_dims, CFL_SIZE); } ISMRMRD_Acquisition acq; for (unsigned int i = 0; i < number_of_acquisitions; i++) { ismrmrd_init_acquisition(&acq); ismrmrd_read_acquisition(&d, i, &acq); if (acq.head.flags & (1 << (ISMRMRD_ACQ_IS_NOISE_MEASUREMENT - 1))) continue; if (-1 == channels) { channels = acq.head.available_channels; samples = acq.head.number_of_samples; } pos[1] = acq.head.idx.kspace_encode_step_1; pos[2] = acq.head.idx.kspace_encode_step_2; pos[4] = slices; // acq.head.idx.slice; if (buf != NULL) { assert(pos[1] < dims[1]); assert(pos[2] < dims[2]); assert(pos[4] < dims[4]); assert(dims[0] == acq.head.number_of_samples); assert(dims[3] == acq.head.active_channels); assert(dims[3] == acq.head.available_channels); debug_printf(DP_DEBUG3, ":/%ld %ld/%ld %ld/%ld :/%ld %ld/%ld %d\n", dims[0], pos[1], dims[1], pos[2], dims[2], dims[3], pos[4], dims[4], number_of_acquisitions); md_copy_block2(DIMS, pos, dims, strs, buf, adc_dims, adc_strs, acq.data, CFL_SIZE); } else { dims[1] = MAX(dims[1], pos[1] + 1); dims[2] = MAX(dims[2], pos[2] + 1); } if (acq.head.flags & (1 << (ISMRMRD_ACQ_LAST_IN_SLICE - 1))) slices++; // ismrmrd_free_acquisition(&acq); } if (NULL == buf) { dims[0] = samples; dims[3] = channels; dims[4] = slices; } else { assert(dims[3] == channels); assert(dims[4] == slices); } // printf("Done.\n"); return 0; } bart-0.5.00/src/ismrm/read.h000066400000000000000000000002611353046746100155360ustar00rootroot00000000000000 #include "misc/mri.h" #ifdef __cplusplus extern "C" { #endif extern int ismrm_read(const char* datafile, long dims[DIMS], _Complex float* buf); #ifdef __cplusplus } #endif bart-0.5.00/src/ismrmrd.c000066400000000000000000000024531353046746100151510ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/mri.h" #include "ismrm/read.h" static const char usage_str[] = " "; static const char help_str[] = "Import ISMRM raw data files.\n"; int main_ismrmrd(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); long dims[DIMS]; printf("Reading headers... "); fflush(stdout); if (-1 == ismrm_read(argv[1], dims, NULL)) { fprintf(stderr, "Reading headers failed.\n"); return 1; } printf("done.\n"); printf("Dimensions:"); unsigned int i; for (i = 0; i < DIMS; i++) printf(" %ld", dims[i]); printf("\n"); complex float* out = create_cfl(argv[2], DIMS, dims); md_clear(DIMS, dims, out, CFL_SIZE); printf("Reading data... "); fflush(stdout); if (-1 == ismrm_read(argv[1], dims, out)) { fprintf(stderr, "Reading data failed.\n"); return 1; } printf("done.\n"); unmap_cfl(DIMS, dims, out); return 0; } bart-0.5.00/src/iter/000077500000000000000000000000001353046746100142675ustar00rootroot00000000000000bart-0.5.00/src/iter/admm.c000066400000000000000000000266341353046746100153640ustar00rootroot00000000000000/* Copyright 2014-2018. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2018 Martin Uecker * 2014-2017 Jon Tamir * * * * Glowinski R and Marroco A. Sur l'approximation, par elements finis * d'ordre un, et la resolution, par penalisation-dualite d'une classe * de problemes de Dirichlet non lineaires. ESAIM: Mathematical * Modelling and Numerical Analysis - Modelisation Mathematique * et Analyse Numerique 9.R2: 41-76 (1975) * * Daniel Gabay and Bertrand Mercier. * A dual algorithm for the solution of nonlinear variational problems * via finite element approximation * Computers & Mathematics with Applications, 2:17-40 (1976) * * Afonso MA, Bioucas-Dias JM, Figueiredo M. An Augmented Lagrangian Approach to * the Constrained Optimization Formulation of Imaging Inverse Problems, * IEEE Trans Image Process, 20:681-695 (2011) * * Boyd S, Parikh N, Chu E, Peleato B, Eckstein J. Distributed Optimization and * Statistical Learning via the Alternating Direction Method of Multipliers, * Foundations and Trends in Machine Learning, 3:1-122 (2011) * * Wohlberg B. ADMM Penalty Parameter Selection by Residual Balancing, * arXiv:1704.06209 (2017) * */ #include #include #include #include "num/ops.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/types.h" #include "iter/italgos.h" #include "iter/vec.h" #include "iter/monitor.h" #include "admm.h" DEF_TYPEID(admm_history_s); struct admm_normaleq_data { INTERFACE(iter_op_data); long N; unsigned int num_funs; struct admm_op* ops; float rho; const struct vec_iter_s* vops; unsigned int nr_invokes; struct iter_op_s Aop; }; static DEF_TYPEID(admm_normaleq_data); static void admm_normaleq(iter_op_data* _data, float* dst, const float* src) { auto data = CAST_DOWN(admm_normaleq_data, _data); float* tmp = data->vops->allocate(data->N); data->vops->clear(data->N, dst); for (unsigned int i = 0; i < data->num_funs; i++) { iter_op_call(data->ops[i].normal, tmp, src); if (NULL != data->Aop.fun) data->vops->axpy(data->N, dst, data->rho, tmp); else data->vops->add(data->N, dst, dst, tmp); } data->nr_invokes++; if (NULL != data->Aop.fun) { iter_op_call(data->Aop, tmp, src); data->vops->add(data->N, dst, dst, tmp); } data->vops->del(tmp); } struct cg_xupdate_s { INTERFACE(iter_op_data); unsigned int N; const struct vec_iter_s* vops; unsigned int maxitercg; float cg_eps; struct admm_normaleq_data* ndata; struct iter_monitor_s* monitor; }; static DEF_TYPEID(cg_xupdate_s); static void cg_xupdate(iter_op_data* _data, float rho, float* x, const float* rhs) { auto data = CAST_DOWN(cg_xupdate_s, _data); assert(data->ndata->rho == rho); data->ndata->nr_invokes--; // undo counting in admm float eps = data->vops->norm(data->N, rhs); // data->vops->clear(data->N, x); if (0. == eps) // x should have been initialized already return; conjgrad(data->maxitercg, 0., data->cg_eps * eps, data->N, data->vops, (struct iter_op_s){ admm_normaleq, CAST_UP(data->ndata) }, x, rhs, data->monitor); data->ndata->nr_invokes--; // subtract one for initialization in conjgrad } static long sum_long_array(unsigned int N, const long a[N]) { return ((0 == N) ? 0 : (a[0] + sum_long_array(N - 1, a + 1))); } /* * ADMM (ADMM-2 from Afonso et al.) * * Solves min_x 0.5 || y - Ax ||_2^2 + sum_i f_i(G_i x - b_i), where the f_i are * arbitrary convex functions. If Aop is NULL, solves min_x sum_i f_i(G_i x - b_i) * * Each iteration requires solving the proximal of f_i, as well as applying * G_i, G_i^H, and G_i^H G_i, all which must be provided in admm_plan_s. * The b_i are offsets (biases) that should also be provided in admm_plan_s. */ void admm(const struct admm_plan_s* plan, unsigned int D, const long z_dims[D], long N, float* x, const float* x_adj, const struct vec_iter_s* vops, struct iter_op_s Aop, struct iter_monitor_s* monitor) { unsigned int num_funs = D; float* rhs = vops->allocate(N); float* s = vops->allocate(N); float* GH_usum = NULL; float* z[num_funs ?:1]; float* u[num_funs ?:1]; float* r[num_funs ?:1]; for (unsigned int j = 0; j < num_funs; j++) { z[j] = vops->allocate(z_dims[j]); u[j] = vops->allocate(z_dims[j]); r[j] = vops->allocate(z_dims[j]); } if (!plan->fast) GH_usum = vops->allocate(N); float rho = plan->rho; float tau = plan->tau; struct admm_normaleq_data ndata = { .INTERFACE.TYPEID = &TYPEID(admm_normaleq_data), .N = N, .num_funs = num_funs, .ops = plan->ops, .Aop = Aop, .rho = 1., .vops = vops, .nr_invokes = 0, }; struct iter_op_p_s xupdate = plan->xupdate; struct cg_xupdate_s cg_xupdate_data = { .INTERFACE.TYPEID = &TYPEID(cg_xupdate_s), .N = N, .vops = vops, .maxitercg = plan->maxitercg, .cg_eps = plan->cg_eps, .ndata = &ndata, .monitor = monitor, }; if (NULL == xupdate.fun) xupdate = (struct iter_op_p_s){ cg_xupdate, CAST_UP(&cg_xupdate_data) }; // hogwild int hw_K = 1; int hw_k = 0; const float* biases[num_funs ?:1]; for (unsigned int j = 0; j < num_funs; j++) biases[j] = (NULL != plan->biases) ? plan->biases[j] : NULL; // compute norm of biases -- for eps_primal double n3 = 0.; if (!plan->fast) { for (unsigned int j = 0; j < num_funs; j++) if (biases[j] != NULL) n3 += pow(vops->norm(z_dims[j], biases[j]), 2.); } if (plan->do_warmstart) { for (unsigned int j = 0; j < num_funs; j++) { // initialize for j'th function update float* Gjx_plus_uj = vops->allocate(z_dims[j]); iter_op_call(plan->ops[j].forward, Gjx_plus_uj, x); // Gj(x) if (NULL != biases[j]) vops->sub(z_dims[j], Gjx_plus_uj, Gjx_plus_uj, biases[j]); if (0. == rho) vops->copy(z_dims[j], z[j], Gjx_plus_uj); else iter_op_p_call(plan->prox_ops[j], 1. / rho, z[j], Gjx_plus_uj); vops->sub(z_dims[j], u[j], Gjx_plus_uj, z[j]); vops->del(Gjx_plus_uj); } } else { for (unsigned int j = 0; j < num_funs; j++) { vops->clear(z_dims[j], z[j]); vops->clear(z_dims[j], u[j]); } } for (unsigned int i = 0; i < plan->maxiter; i++) { iter_monitor(monitor, vops, x); // update x vops->clear(N, rhs); for (unsigned int j = 0; j < num_funs; j++) { vops->sub(z_dims[j], r[j], z[j], u[j]); if (NULL != biases[j]) vops->add(z_dims[j], r[j], r[j], biases[j]); iter_op_call(plan->ops[j].adjoint, s, r[j]); vops->add(N, rhs, rhs, s); } if (NULL != Aop.fun) { vops->xpay(N, rho, rhs, x_adj); } ndata.rho = rho; iter_op_p_call(xupdate, rho, x, rhs); ndata.nr_invokes++; double n1 = 0.; if (!plan->fast) { vops->clear(N, GH_usum); vops->clear(N, s); for (unsigned int j = 0; j < num_funs; j++) vops->clear(z_dims[j], r[j]); } // z_j prox for (unsigned int j = 0; j < num_funs; j++) { // initialize for j'th function update float* Gjx_plus_uj = vops->allocate(z_dims[j]); float* zj_old = vops->allocate(z_dims[j]); iter_op_call(plan->ops[j].forward, Gjx_plus_uj, x); // Gj(x) // over-relaxation: Gjx_hat = alpha * Gj(x) + (1 - alpha) * (zj_old + bj) if (!plan->fast) { vops->copy(z_dims[j], zj_old, z[j]); vops->copy(z_dims[j], r[j], Gjx_plus_uj); // rj = Gj(x) n1 += pow(vops->norm(z_dims[j], r[j]), 2.); vops->smul(z_dims[j], plan->alpha, Gjx_plus_uj, Gjx_plus_uj); vops->axpy(z_dims[j], Gjx_plus_uj, (1. - plan->alpha), z[j]); if (NULL != biases[j]) vops->axpy(z_dims[j], Gjx_plus_uj, (1. - plan->alpha), biases[j]); } vops->add(z_dims[j], Gjx_plus_uj, Gjx_plus_uj, u[j]); // Gj(x) + uj if (NULL != biases[j]) vops->sub(z_dims[j], Gjx_plus_uj, Gjx_plus_uj, biases[j]); // Gj(x) - bj + uj if (0. == rho) vops->copy(z_dims[j], z[j], Gjx_plus_uj); else iter_op_p_call(plan->prox_ops[j], 1. / rho, z[j], Gjx_plus_uj); vops->sub(z_dims[j], u[j], Gjx_plus_uj, z[j]); vops->del(Gjx_plus_uj); if (!plan->fast) { // rj = rj - zj - bj = Gj(x) - zj - bj vops->sub(z_dims[j], r[j], r[j], z[j]); if (NULL != biases[j]) vops->sub(z_dims[j], r[j], r[j], biases[j]); // add next term to s: s = s + Gj^H (zj - zj_old) vops->sub(z_dims[j], zj_old, z[j], zj_old); iter_op_call(plan->ops[j].adjoint, rhs, zj_old); vops->add(N, s, s, rhs); // GH_usum += G_j^H uj (for updating eps_dual) iter_op_call(plan->ops[j].adjoint, rhs, u[j]); vops->add(N, GH_usum, GH_usum, rhs); } vops->del(zj_old); } float s_norm = 0.; float r_norm = 0.; double s_scaling = 1.; double r_scaling = 1.; if (plan->dynamic_rho || !plan->fast) { s_norm = rho * vops->norm(N, s); r_norm = 0.; for (unsigned int j = 0; j < num_funs; j++) r_norm += pow(vops->norm(z_dims[j], r[j]), 2.); r_norm = sqrt(r_norm); } if (!plan->fast) { double n2 = 0.; for (unsigned int j = 0; j < num_funs; j++) n2 += pow(vops->norm(z_dims[j], z[j]), 2.); r_scaling = sqrt(MAX(MAX(n1, n2), n3)); s_scaling = rho * vops->norm(N, GH_usum); long M = sum_long_array(num_funs, z_dims); float eps_pri = plan->ABSTOL * sqrt(M) + plan->RELTOL * r_scaling; float eps_dual = plan->ABSTOL * sqrt(N) + plan->RELTOL * s_scaling; struct admm_history_s history; history.s_norm = s_norm; history.r_norm = r_norm; history.s_scaling = s_scaling; history.r_scaling = r_scaling; history.eps_pri = eps_pri; history.eps_dual = eps_dual; history.rho = rho; history.tau = tau; history.numiter = i; history.nr_invokes = ndata.nr_invokes; iter_history(monitor, CAST_UP(&history)); if (0 == i) debug_printf(DP_DEBUG2, "%3s\t%3s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\t%10s\n", "iter", "cgiter", "rho", "tau", "r norm", "eps pri", "s norm", "eps dual", "obj", "relMSE"); debug_printf(DP_DEBUG2, "%3d\t%3d\t%10.4f\t%10.4f\t%10.4f\t%10.4f\t%10.4f\t%10.4f\t%10.4f\t%10.4f\n", history.numiter, history.nr_invokes, history.rho, history.tau, history.r_norm, history.eps_pri, history.s_norm, history.eps_dual, (NULL == monitor) ? -1. : monitor->obj, (NULL == monitor) ? -1. : monitor->err); if ( (ndata.nr_invokes > plan->maxiter) || ( (r_norm < eps_pri) && (s_norm < eps_dual))) break; } else { debug_printf(DP_DEBUG3, "### ITER: %d (%d)\n", i, ndata.nr_invokes); if (ndata.nr_invokes > plan->maxiter) break; } float sc = 1.; assert(!(plan->dynamic_rho && plan->hogwild)); if (plan->dynamic_tau) { double t = sqrt(r_norm / s_norm); if (plan->tau_max > t && 1 <= t) tau = t; else if (1 > t && (1/plan->tau_max) < t) tau = 1. / t; else tau = plan->tau_max; } if (plan->dynamic_rho) { double r = r_norm; double s = s_norm; if (plan->relative_norm) { r /= r_scaling; s /= s_scaling; } if (r > plan->mu * s) sc = tau; else if (s > plan->mu * r) sc = 1. / tau; } if (plan->hogwild) { hw_k++; if (hw_k == hw_K) { hw_k = 0; hw_K *= 2; sc = 2.; } } if (1. != sc) { rho = rho * sc; for (unsigned int j = 0; j < num_funs; j++) vops->smul(z_dims[j], 1. / sc, u[j], u[j]); } } // cleanup vops->del(rhs); vops->del(s); for (unsigned int j = 0; j < num_funs; j++) { vops->del(z[j]); vops->del(u[j]); vops->del(r[j]); } if (!plan->fast) vops->del(GH_usum); } bart-0.5.00/src/iter/admm.h000066400000000000000000000062011353046746100153550ustar00rootroot00000000000000/* Copyright 2014-2018. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __ADMM_H #define __ADMM_H #include "misc/cppwrap.h" #include "misc/types.h" #include "iter/monitor.h" #include "iter/italgos.h" struct vec_iter_s; struct admm_op { struct iter_op_s forward; struct iter_op_s adjoint; struct iter_op_s normal; }; /** * Parameters for ADMM version 1 * * @param maxiter maximum number of iterations (gradient evaluations) before terminating * @param maxitercg maximum number of conjugate gradient iterations for updating x * @param num_funs number of convex functions in objective, excluding data consistency * * @param do_warmstart do not zero out primal and dual variables before starting * @param dynamic_rho update rho according to mu/tau rule * @param hogwild_rho update rho according to Hogwild rule (increase exponentially) * * @param ABSTOL used for early stopping condition * @param RELTOL used for early stopping condition * * @param rho -- augmented lagrangian penalty parameter * @param alpha -- over-relaxation parameter between (0, 2) * * @param tau -- multiply/divide rho by tau if residuals are more than mu times apart * @param mu -- multiply/divide rho by tau if residuals are more than mu times apart * * @param funs array of prox functions (size is num_funs) * * @param ops array of operators, G_i (size is num_funs) * @param prox_ops array of proximal functions (size is num_funs) * @param biases array of biases/offsets (size is num_funs) * * @param image_truth truth image for computing relMSE */ struct admm_plan_s { unsigned int maxiter; unsigned int maxitercg; float cg_eps; _Bool do_warmstart; _Bool dynamic_rho; _Bool dynamic_tau; _Bool relative_norm; _Bool hogwild; _Bool fast; double ABSTOL; double RELTOL; float rho; float alpha; float tau; float tau_max; float mu; unsigned int num_funs; struct iter_op_p_s* prox_ops; struct admm_op* ops; const float* const* biases; struct iter_op_p_s xupdate; }; /** * Store ADMM history * * @param numiter actual number of iterations run * @param r_norm primal residual norm at each iteration * @param s_norm dual residual norm at each iteration * @param r_scaling relative scaling of primary residual norm at each iteration * @param s_scaling relative scaling of dual residual norm at each iteration * @param eps_pri primal epsilon at each iteration * @param eps_dual dual epsilon at each iteration * @param rho ADMM penalty parameter at each iteration */ struct admm_history_s { INTERFACE(iter_history_t); unsigned int numiter; unsigned int nr_invokes; double r_norm; double s_norm; double r_scaling; double s_scaling; double eps_pri; double eps_dual; float rho; float tau; }; extern void admm(const struct admm_plan_s* plan, unsigned int D, const long z_dims[__VLA(D)], long N, float* x, const float* x_adj, const struct vec_iter_s* vops, struct iter_op_s Aop, struct iter_monitor_s* monitor); #include "misc/cppwrap.h" #endif // __ADMM_H bart-0.5.00/src/iter/italgos.c000066400000000000000000000374121353046746100161040ustar00rootroot00000000000000/* Copyright 2013-2017. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2013-2014 Frank Ong * 2013-2014,2017 Jon Tamir * * * * Landweber L. An iteration formula for Fredholm integral equations of the * first kind. Amer. J. Math. 1951; 73, 615-624. * * Nesterov Y. A method of solving a convex programming problem with * convergence rate O (1/k2). Soviet Mathematics Doklady 1983; 27(2):372-376 * * Bakushinsky AB. Iterative methods for nonlinear operator equations without * regularity. New approach. In Dokl. Russian Acad. Sci 1993; 330:282-284. * * Daubechies I, Defrise M, De Mol C. An iterative thresholding algorithm for * linear inverse problems with a sparsity constraint. * Comm Pure Appl Math 2004; 57:1413-1457. * * Beck A, Teboulle M. A fast iterative shrinkage-thresholding algorithm for * linear inverse problems. SIAM Journal on Imaging Sciences 2.1 2009; 183-202. * * Chambolle A, Pock, T. A First-Order Primal-Dual Algorithm for Convex Problems * with Applications to Imaging. J. Math. Imaging Vis. 2011; 40, 120-145. * */ #include #include #include "misc/misc.h" #include "misc/debug.h" #include "iter/vec.h" #include "iter/monitor.h" #include "italgos.h" extern inline void iter_op_call(struct iter_op_s op, float* dst, const float* src); extern inline void iter_nlop_call(struct iter_nlop_s op, int N, float* args[N]); extern inline void iter_op_p_call(struct iter_op_p_s op, float rho, float* dst, const float* src); /** * ravine step * (Nesterov 1983) */ static void ravine(const struct vec_iter_s* vops, long N, float* ftp, float* xa, float* xb) { float ft = *ftp; float tfo = ft; ft = (1.f + sqrtf(1.f + 4.f * ft * ft)) / 2.f; *ftp = ft; vops->swap(N, xa, xb); vops->axpy(N, xa, (1.f - tfo) / ft - 1.f, xa); vops->axpy(N, xa, (tfo - 1.f) / ft + 1.f, xb); } void landweber_sym(unsigned int maxiter, float epsilon, float alpha, long N, const struct vec_iter_s* vops, struct iter_op_s op, float* x, const float* b, struct iter_monitor_s* monitor) { float* r = vops->allocate(N); double rsnot = vops->norm(N, b); for (unsigned int i = 0; i < maxiter; i++) { iter_monitor(monitor, vops, x); iter_op_call(op, r, x); // r = A x vops->xpay(N, -1., r, b); // r = b - r = b - A x double rsnew = vops->norm(N, r); debug_printf(DP_DEBUG3, "#%d: %f\n", i, rsnew / rsnot); if (rsnew < epsilon) break; vops->axpy(N, x, alpha, r); } vops->del(r); } /** * Iterative Soft Thresholding * * @param maxiter maximum number of iterations * @param epsilon stop criterion * @param tau (step size) weighting on the residual term, A^H (b - Ax) * @param N size of input, x * @param vops vector ops definition * @param op linear operator, e.g. A * @param thresh threshold function, e.g. complex soft threshold * @param x initial estimate * @param b observations * @param monitor compute objective value, errors, etc. */ void ist(unsigned int maxiter, float epsilon, float tau, long N, const struct vec_iter_s* vops, ist_continuation_t ist_continuation, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor) { struct ist_data itrdata = { .rsnew = 1., .rsnot = 1., .iter = 0, .maxiter = maxiter, .tau = tau, .scale = 1., }; float* r = vops->allocate(N); itrdata.rsnot = vops->norm(N, b); for (itrdata.iter = 0; itrdata.iter < maxiter; itrdata.iter++) { iter_monitor(monitor, vops, x); if (NULL != ist_continuation) ist_continuation(&itrdata); iter_op_p_call(thresh, itrdata.scale * itrdata.tau, x, x); iter_op_call(op, r, x); // r = A x vops->xpay(N, -1., r, b); // r = b - r = b - A x itrdata.rsnew = vops->norm(N, r); debug_printf(DP_DEBUG3, "#It %03d: %f \n", itrdata.iter, itrdata.rsnew / itrdata.rsnot); if (itrdata.rsnew < epsilon) break; vops->axpy(N, x, itrdata.tau, r); } debug_printf(DP_DEBUG3, "\n"); vops->del(r); } /** * Iterative Soft Thresholding/FISTA to solve min || b - Ax ||_2 + lambda || T x ||_1 * * @param maxiter maximum number of iterations * @param epsilon stop criterion * @param tau (step size) weighting on the residual term, A^H (b - Ax) * @param N size of input, x * @param vops vector ops definition * @param op linear operator, e.g. A * @param thresh threshold function, e.g. complex soft threshold * @param x initial estimate * @param b observations */ void fista(unsigned int maxiter, float epsilon, float tau, long N, const struct vec_iter_s* vops, ist_continuation_t ist_continuation, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor) { struct ist_data itrdata = { .rsnew = 1., .rsnot = 1., .iter = 0, .maxiter = maxiter, .tau = tau, .scale = 1., }; float* r = vops->allocate(N); float* o = vops->allocate(N); float ra = 1.; vops->copy(N, o, x); itrdata.rsnot = vops->norm(N, b); for (itrdata.iter = 0; itrdata.iter < maxiter; itrdata.iter++) { iter_monitor(monitor, vops, x); if (NULL != ist_continuation) ist_continuation(&itrdata); iter_op_p_call(thresh, itrdata.scale * itrdata.tau, x, x); ravine(vops, N, &ra, x, o); // FISTA iter_op_call(op, r, x); // r = A x vops->xpay(N, -1., r, b); // r = b - r = b - A x itrdata.rsnew = vops->norm(N, r); debug_printf(DP_DEBUG3, "#It %03d: %f \n", itrdata.iter, itrdata.rsnew / itrdata.rsnot); if (itrdata.rsnew < epsilon) break; vops->axpy(N, x, itrdata.tau, r); } debug_printf(DP_DEBUG3, "\n"); debug_printf(DP_DEBUG2, "\t\tFISTA iterations: %u\n", itrdata.iter); vops->del(o); vops->del(r); } /** * Landweber L. An iteration formula for Fredholm integral equations of the * first kind. Amer. J. Math. 1951; 73, 615-624. */ void landweber(unsigned int maxiter, float epsilon, float alpha, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_s adj, float* x, const float* b, struct iter_op_s callback, struct iter_monitor_s* monitor) { float* r = vops->allocate(M); float* p = vops->allocate(N); double rsnot = vops->norm(M, b); for (unsigned int i = 0; i < maxiter; i++) { iter_monitor(monitor, vops, x); iter_op_call(op, r, x); // r = A x vops->xpay(M, -1., r, b); // r = b - r = b - A x double rsnew = vops->norm(M, r); debug_printf(DP_DEBUG3, "#%d: %f\n", i, rsnew / rsnot); if (rsnew < epsilon) break; iter_op_call(adj, p, r); vops->axpy(N, x, alpha, p); if (NULL != callback.fun) iter_op_call(callback, x, x); } vops->del(r); vops->del(p); } /** * Conjugate Gradient Descent to solve Ax = b for symmetric A * * @param maxiter maximum number of iterations * @param regularization parameter * @param epsilon stop criterion * @param N size of input, x * @param vops vector ops definition * @param linop linear operator, i.e. A * @param x initial estimate * @param b observations */ float conjgrad(unsigned int maxiter, float l2lambda, float epsilon, long N, const struct vec_iter_s* vops, struct iter_op_s linop, float* x, const float* b, struct iter_monitor_s* monitor) { float* r = vops->allocate(N); float* p = vops->allocate(N); float* Ap = vops->allocate(N); // The first calculation of the residual might not // be necessary in some cases... iter_op_call(linop, r, x); // r = A x vops->axpy(N, r, l2lambda, x); vops->xpay(N, -1., r, b); // r = b - r = b - A x vops->copy(N, p, r); // p = r float rsnot = (float)pow(vops->norm(N, r), 2.); float rsold = rsnot; float rsnew = rsnot; float eps_squared = pow(epsilon, 2.); unsigned int i = 0; if (0. == rsold) { debug_printf(DP_DEBUG3, "CG: early out\n"); goto cleanup; } for (i = 0; i < maxiter; i++) { iter_monitor(monitor, vops, x); debug_printf(DP_DEBUG3, "#%d: %f\n", i, (double)sqrtf(rsnew)); iter_op_call(linop, Ap, p); // Ap = A p vops->axpy(N, Ap, l2lambda, p); float pAp = (float)vops->dot(N, p, Ap); if (0. == pAp) break; float alpha = rsold / pAp; vops->axpy(N, x, +alpha, p); vops->axpy(N, r, -alpha, Ap); rsnew = pow(vops->norm(N, r), 2.); float beta = rsnew / rsold; rsold = rsnew; if (rsnew <= eps_squared) break; vops->xpay(N, beta, p, r); // p = beta * p + r } cleanup: vops->del(Ap); vops->del(p); vops->del(r); debug_printf(DP_DEBUG2, "\t cg: %3d\n", i); return sqrtf(rsnew); } /** * Iteratively Regularized Gauss-Newton Method * (Bakushinsky 1993) * * y = F(x) = F xn + DF dx + ... * * IRGNM: DF^H ((y - F xn) + DF (xn - x0)) = ( DF^H DF + alpha ) (dx + xn - x0) * DF^H ((y - F xn)) - alpha (xn - x0) = ( DF^H DF + alpha) dx * * This version only solves the second equation for the update 'dx'. This corresponds * to a least-squares problem where the quadratic regularization applies to the difference * to 'x0'. */ void irgnm(unsigned int iter, float alpha, float alpha_min, float redu, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_s adj, struct iter_op_p_s inv, float* x, const float* xref, const float* y, struct iter_op_s callback, struct iter_monitor_s* monitor) { float* r = vops->allocate(M); float* p = vops->allocate(N); float* h = vops->allocate(N); for (unsigned int i = 0; i < iter; i++) { iter_monitor(monitor, vops, x); iter_op_call(op, r, x); // r = F x vops->xpay(M, -1., r, y); // r = y - F x debug_printf(DP_DEBUG2, "Step: %u, Res: %f\n", i, vops->norm(M, r)); iter_op_call(adj, p, r); if (NULL != xref) vops->axpy(N, p, +alpha, xref); vops->axpy(N, p, -alpha, x); iter_op_p_call(inv, alpha, h, p); vops->axpy(N, x, 1., h); alpha = (alpha - alpha_min) / redu + alpha_min; if (NULL != callback.fun) iter_op_call(callback, x, x); } vops->del(h); vops->del(p); vops->del(r); } /** * Iteratively Regularized Gauss-Newton Method * (Bakushinsky 1993) * * y = F(x) = F xn + DF dx + ... * * IRGNM: R(DF^H, DF^H DF, alpha) ((y - F xn) + DF (xn - x0)) = (dx + xn - x0) * * This version has an extra call to DF, but we can use a generic regularized * least-squares solver. */ void irgnm2(unsigned int iter, float alpha, float alpha_min, float alpha_min0, float redu, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_s der, struct iter_op_p_s lsqr, float* x, const float* xref, const float* y, struct iter_op_s callback, struct iter_monitor_s* monitor) { float* r = vops->allocate(M); float* q = vops->allocate(M); for (unsigned int i = 0; i < iter; i++) { iter_monitor(monitor, vops, x); iter_op_call(op, r, x); // r = F x vops->xpay(M, -1., r, y); // r = y - F x debug_printf(DP_DEBUG2, "Step: %u, Res: %f\n", i, vops->norm(M, r)); if (NULL != xref) vops->axpy(N, x, -1., xref); iter_op_call(der, q, x); vops->axpy(M, r, +1., q); iter_op_p_call(lsqr, alpha, x, r); if (NULL != xref) vops->axpy(N, x, +1., xref); alpha = (alpha - alpha_min) / redu + alpha_min; if (alpha < alpha_min0) alpha = alpha_min0; if (NULL != callback.fun) iter_op_call(callback, x, x); } vops->del(q); vops->del(r); } /** * Alternating Minimzation * * Minimize residual by calling each min_op in turn. */ void altmin(unsigned int iter, float alpha, float redu, long N, const struct vec_iter_s* vops, unsigned int NI, struct iter_nlop_s op, struct iter_op_p_s min_ops[__VLA(NI)], float* x[__VLA(NI)], const float* y, struct iter_nlop_s callback) { float* r = vops->allocate(N); vops->clear(N, r); float* args[1 + NI]; args[0] = r; for (long i = 0; i < NI; ++i) args[1 + i] = x[i]; for (unsigned int i = 0; i < iter; i++) { for (unsigned int j = 0; j < NI; ++j) { iter_nlop_call(op, 1 + NI, args); // r = F x vops->xpay(N, -1., r, y); // r = y - F x debug_printf(DP_DEBUG2, "Step: %u, Res: %f\n", i, vops->norm(N, r)); iter_op_p_call(min_ops[j], alpha, x[j], y); if (NULL != callback.fun) iter_nlop_call(callback, NI, x); } alpha /= redu; } vops->del(r); } /** * Projection onto Convex Sets * * minimize 0 subject to: x in C_1, x in C_2, ..., x in C_D, * where the C_i are convex sets */ void pocs(unsigned int maxiter, unsigned int D, struct iter_op_p_s proj_ops[static D], const struct vec_iter_s* vops, long N, float* x, struct iter_monitor_s* monitor) { UNUSED(N); UNUSED(vops); for (unsigned int i = 0; i < maxiter; i++) { debug_printf(DP_DEBUG3, "#Iter %d\n", i); iter_monitor(monitor, vops, x); for (unsigned int j = 0; j < D; j++) iter_op_p_call(proj_ops[j], 1., x, x); // use temporary memory here? } } /** * Power iteration */ double power(unsigned int maxiter, long N, const struct vec_iter_s* vops, struct iter_op_s op, float* u) { double s = vops->norm(N, u); vops->smul(N, 1. / s, u, u); for (unsigned int i = 0; i < maxiter; i++) { iter_op_call(op, u, u); // r = A x s = vops->norm(N, u); vops->smul(N, 1. / s, u, u); } return s; } /** * Chambolle Pock First Order Primal Dual algorithm. Solves min_x F(Ax) + G(x) * * @param maxiter maximum number of iterations * @param epsilon stop criterion * @param tau primal step size * @param sigma dual step size * @param decay decay rate * @param theta convex combination rate * @param N size of input, x * @param M size of transformed input, Ax * @param vops vector ops definition * @param op_forw forward operator, A * @param op_adj adjoint operator, AH * @param prox1 proximal function of F, e.g. prox_l2ball * @param prox2 proximal function of G, e.g. prox_wavelet_thresh * @param x initial estimate * @param monitor callback function */ void chambolle_pock(unsigned int maxiter, float epsilon, float tau, float sigma, float theta, float decay, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op_forw, struct iter_op_s op_adj, struct iter_op_p_s prox1, struct iter_op_p_s prox2, float* x, struct iter_monitor_s* monitor) { float* x_avg = vops->allocate(N); float* x_old = vops->allocate(N); float* x_new = vops->allocate(N); float* u_old = vops->allocate(M); float* u = vops->allocate(M); float* u_new = vops->allocate(M); vops->copy(N, x_old, x); vops->copy(N, x_new, x); vops->copy(N, x_avg, x); vops->clear(M, u); vops->clear(M, u_new); vops->clear(M, u_old); for (unsigned int i = 0; i < maxiter; i++) { float lambda = (float)pow(decay, i); /* update u * u0 = u * p = u + sigma * A(x) * u = p - sigma * prox1(p / sigma, 1 / sigma) * u = lambda * u + (1 - lambda) * u0 */ iter_op_call(op_forw, u_old, x_avg); vops->axpy(M, u_old, 1. / sigma, u); // (u + sigma * A(x)) / sigma iter_op_p_call(prox1, 1. / sigma, u_new, u_old); vops->axpbz(M, u_new, -1. * sigma, u_new, sigma, u_old); vops->copy(M, u_old, u); vops->axpbz(M, u, lambda, u_new, 1. - lambda, u_old); /* update x * x0 = x * q = x0 - tau * AH(u) * x = prox2(q, tau) * x = lambda * x + (1 - lambda * x0) */ vops->copy(N, x_old, x); iter_op_call(op_adj, x_new, u); vops->axpy(N, x, -1. * tau, x_new); iter_op_p_call(prox2, tau, x_new, x); vops->axpbz(N, x, lambda, x_new, 1. - lambda, x_old); /* update x_avg * a_avg = x + theta * (x - x0) */ vops->axpbz(N, x_avg, 1 + theta, x, -1. * theta, x_old); // residual vops->sub(N, x_old, x, x_old); vops->sub(M, u_old, u, u_old); float res1 = vops->norm(N, x_old) / sigma; float res2 = vops->norm(M, u_old) / tau; iter_monitor(monitor, vops, x); debug_printf(DP_DEBUG3, "#It %03d: %f %f \n", i, res1, res2); if (epsilon > (res1 + res2)) break; } debug_printf(DP_DEBUG3, "\n"); vops->del(x_avg); vops->del(x_old); vops->del(x_new); vops->del(u_old); vops->del(u); vops->del(u_new); } bart-0.5.00/src/iter/italgos.h000066400000000000000000000107221353046746100161040ustar00rootroot00000000000000/* Copyright 2013-2017. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __ITALGOS_H #define __ITALGOS_H #include "misc/cppwrap.h" #ifndef NUM_INTERNAL // #warning "Use of private interfaces" #endif #include "misc/types.h" #include "misc/nested.h" struct vec_iter_s; #ifndef ITER_OP_DATA_S #define ITER_OP_DATA_S typedef struct iter_op_data_s { TYPEID* TYPEID; } iter_op_data; #endif typedef void (*iter_op_fun_t)(iter_op_data* data, float* dst, const float* src); typedef void (*iter_nlop_fun_t)(iter_op_data* data, int N, float* args[N]); typedef void (*iter_op_p_fun_t)(iter_op_data* data, float rho, float* dst, const float* src); struct iter_op_s { iter_op_fun_t fun; iter_op_data* data; }; struct iter_nlop_s { iter_nlop_fun_t fun; iter_op_data* data; }; struct iter_op_p_s { iter_op_p_fun_t fun; iter_op_data* data; }; inline void iter_op_call(struct iter_op_s op, float* dst, const float* src) { op.fun(op.data, dst, src); } inline void iter_nlop_call(struct iter_nlop_s op, int N, float* args[N]) { op.fun(op.data, N, args); } inline void iter_op_p_call(struct iter_op_p_s op, float rho, float* dst, const float* src) { op.fun(op.data, rho, dst, src); } struct iter_monitor_s; float conjgrad(unsigned int maxiter, float l2lambda, float epsilon, long N, const struct vec_iter_s* vops, struct iter_op_s linop, float* x, const float* b, struct iter_monitor_s* monitor); void landweber(unsigned int maxiter, float epsilon, float alpha, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_s adj, float* x, const float* b, struct iter_op_s callback, struct iter_monitor_s* monitor); void landweber_sym(unsigned int maxiter, float epsilon, float alpha, long N, const struct vec_iter_s* vops, struct iter_op_s op, float* x, const float* b, struct iter_monitor_s* monitor); /** * Store information about iterative algorithm. * Used to flexibly modify behavior, e.g. continuation * * @param rsnew current residual * @param rsnot initial residual * @param iter current iteration * @param maxiter maximum iteration * @param tau tau * @param scale scaling of regularization */ struct ist_data { double rsnew; double rsnot; unsigned int iter; const unsigned int maxiter; float tau; float scale; }; typedef void CLOSURE_TYPE(ist_continuation_t)(struct ist_data* itrdata); void ist(unsigned int maxiter, float epsilon, float tau, long N, const struct vec_iter_s* vops, ist_continuation_t ist_continuation, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor); void fista(unsigned int maxiter, float epsilon, float tau, long N, const struct vec_iter_s* vops, ist_continuation_t ist_continuation, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor); void irgnm(unsigned int iter, float alpha, float alpha_min, float redu, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_s adj, struct iter_op_p_s inv, float* x, const float* x0, const float* y, struct iter_op_s callback, struct iter_monitor_s* monitor); void irgnm2(unsigned int iter, float alpha, float alpha_min, float alpha0, float redu, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_s der, struct iter_op_p_s lsqr, float* x, const float* xref, const float* y, struct iter_op_s callback, struct iter_monitor_s* monitor); void altmin(unsigned int iter, float alpha, float redu, long N, const struct vec_iter_s* vops, unsigned int NI, struct iter_nlop_s op, struct iter_op_p_s min_ops[__VLA(NI)], float* x[__VLA(NI)], const float* y, struct iter_nlop_s callback); void pocs(unsigned int maxiter, unsigned int D, struct iter_op_p_s proj_ops[__VLA(D)], const struct vec_iter_s* vops, long N, float* x, struct iter_monitor_s* monitor); double power(unsigned int maxiter, long N, const struct vec_iter_s* vops, struct iter_op_s op, float* u); void chambolle_pock(unsigned int maxiter, float epsilon, float tau, float sigma, float theta, float decay, long N, long M, const struct vec_iter_s* vops, struct iter_op_s op_forw, struct iter_op_s op_adj, struct iter_op_p_s thresh1, struct iter_op_p_s thresh2, float* x, struct iter_monitor_s* monitor); #include "misc/cppwrap.h" #endif // __ITALGOS_H bart-0.5.00/src/iter/iter.c000066400000000000000000000130711353046746100154000ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2017. University of Oxford. * Copyright 2018-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * 2014-2018 Jon Tamir * 2014 Frank Ong * 2017 Sofia Dimoudi */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops.h" #include "linops/linop.h" #include "linops/someops.h" #include "iter/italgos.h" #include "iter/prox.h" #include "iter/admm.h" #include "iter/iter2.h" #include "iter/vec.h" #include "misc/debug.h" #include "misc/misc.h" #include "iter.h" DEF_TYPEID(iter_conjgrad_conf); DEF_TYPEID(iter_landweber_conf); DEF_TYPEID(iter_ist_conf); DEF_TYPEID(iter_fista_conf); DEF_TYPEID(iter_chambolle_pock_conf); DEF_TYPEID(iter_pocs_conf); DEF_TYPEID(iter_admm_conf); DEF_TYPEID(iter_niht_conf); DEF_TYPEID(iter_call_s); const struct iter_conjgrad_conf iter_conjgrad_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_conjgrad_conf), .INTERFACE.alpha = 1., .maxiter = 50, .l2lambda = 0., .tol = 0., }; const struct iter_landweber_conf iter_landweber_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_landweber_conf), .INTERFACE.alpha = 1., .maxiter = 50, .step = 0.95, .tol = 0., }; const struct iter_ist_conf iter_ist_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_ist_conf), .INTERFACE.alpha = 1., .maxiter = 50, .step = 0.95, .continuation = 1., .hogwild = false, .tol = 0., }; const struct iter_fista_conf iter_fista_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_fista_conf), .INTERFACE.alpha = 1., .maxiter = 50, .step = 0.95, .continuation = 1., .hogwild = false, .tol = 0., }; const struct iter_admm_conf iter_admm_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_admm_conf), .INTERFACE.alpha = 1., .maxiter = 50, .maxitercg = 10, .cg_eps = 1.E-3, .do_warmstart = false, .dynamic_rho = false, .dynamic_tau = false, .relative_norm = false, .hogwild = false, .fast = false, .ABSTOL = 1.E-4, .RELTOL = 1.E-3, .rho = 0.5, .alpha = 1.6, .tau = 2., .tau_max = 20, .mu = 3, }; const struct iter_pocs_conf iter_pocs_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_pocs_conf), .INTERFACE.alpha = 1., .maxiter = 50, }; const struct iter_niht_conf iter_niht_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_niht_conf), .INTERFACE.alpha = 1., .maxiter = 50, .tol = 1e-8, .do_warmstart = false, }; const struct iter_chambolle_pock_conf iter_chambolle_pock_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter_chambolle_pock_conf), .INTERFACE.alpha = 1., .maxiter = 50, .tol = 1e-8, .theta = 1., .tau = .95, .sigma = .95, .decay = 1., .fast = false, }; typedef void (*thresh_fun_t)(void* data, float lambda, float* dst, const float* src); static bool checkeps(float eps) { if (0. == eps) { debug_printf(DP_WARN, "Warning: data empty\n"); return true; } if (!isnormal(eps)) { debug_printf(DP_WARN, "Warning: data corrupted\n"); return true; } return false; } void iter_conjgrad(iter_conf* _conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { assert(NULL == thresh_prox); iter2_conjgrad(_conf, normaleq_op, 0, NULL, NULL, NULL, NULL, size, image, image_adj, monitor); } void iter_landweber(iter_conf* _conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { auto conf = CAST_DOWN(iter_landweber_conf, _conf); float eps = md_norm(1, MD_DIMS(size), image_adj); if (checkeps(eps)) goto cleanup; assert(NULL == thresh_prox); landweber_sym(conf->maxiter, 1.E-3 * eps, conf->INTERFACE.alpha * conf->step, size, select_vecops(image_adj), OPERATOR2ITOP(normaleq_op), image, image_adj, monitor); cleanup: ; } void iter_ist(iter_conf* _conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { iter2_ist(_conf, normaleq_op, 1, &thresh_prox, NULL, NULL, NULL, size, image, image_adj, monitor); } void iter_fista(iter_conf* _conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { iter2_fista(_conf, normaleq_op, 1, &thresh_prox, NULL, NULL, NULL, size, image, image_adj, monitor); } void iter_admm(iter_conf* _conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { const struct linop_s* eye[1] = { linop_identity_create(1, MD_DIMS(size / 2)) }; // using complex float identity operator... divide size by 2 iter2_admm(_conf, normaleq_op, 1, &thresh_prox, eye, NULL, NULL, size, image, image_adj, monitor); linop_free(eye[0]); } void iter_call_iter2(iter_conf* _conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { auto it = CAST_DOWN(iter2_call_s, _conf); it->fun(it->_conf, normaleq_op, (NULL == thresh_prox) ? 1 : 0, &thresh_prox, NULL, NULL, NULL, size, image, image_adj, monitor); } bart-0.5.00/src/iter/iter.h000066400000000000000000000052201353046746100154020ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __ITER_H #define __ITER_H struct operator_s; struct operator_p_s; #include "misc/types.h" #ifndef ITER_CONF_S #define ITER_CONF_S typedef struct iter_conf_s { TYPEID* TYPEID; float alpha; } iter_conf; #endif struct iter_monitor_s; typedef void italgo_fun_f(iter_conf* conf, const struct operator_s* normaleq_op, const struct operator_p_s* thresh_prox, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor); typedef italgo_fun_f* italgo_fun_t; struct iter_conjgrad_conf { INTERFACE(iter_conf); unsigned int maxiter; float l2lambda; float tol; }; struct iter_landweber_conf { INTERFACE(iter_conf); unsigned int maxiter; float step; float tol; }; struct iter_ist_conf { INTERFACE(iter_conf); unsigned int maxiter; float step; float continuation; _Bool hogwild; float tol; }; struct iter_fista_conf { INTERFACE(iter_conf); unsigned int maxiter; float step; float continuation; _Bool hogwild; float tol; }; struct iter_chambolle_pock_conf { INTERFACE(iter_conf); unsigned int maxiter; float tau; float sigma; float theta; float decay; float tol; _Bool fast; }; struct iter_admm_conf { INTERFACE(iter_conf); unsigned int maxiter; unsigned int maxitercg; float rho; _Bool do_warmstart; _Bool dynamic_rho; _Bool dynamic_tau; _Bool relative_norm; _Bool hogwild; double ABSTOL; double RELTOL; float alpha; float tau; float tau_max; float mu; float cg_eps; _Bool fast; }; struct iter_pocs_conf { INTERFACE(iter_conf); unsigned int maxiter; }; struct iter_niht_conf { INTERFACE(iter_conf); unsigned int maxiter; float tol; _Bool do_warmstart; }; extern const struct iter_conjgrad_conf iter_conjgrad_defaults; extern const struct iter_landweber_conf iter_landweber_defaults; extern const struct iter_ist_conf iter_ist_defaults; extern const struct iter_fista_conf iter_fista_defaults; extern const struct iter_admm_conf iter_admm_defaults; extern const struct iter_pocs_conf iter_pocs_defaults; extern const struct iter_niht_conf iter_niht_defaults; extern const struct iter_chambolle_pock_conf iter_chambolle_pock_defaults; italgo_fun_f iter_conjgrad; italgo_fun_f iter_landweber; italgo_fun_f iter_ist; italgo_fun_f iter_fista; italgo_fun_f iter_admm; // use with iter2_call_s from iter2.h as _conf italgo_fun_f iter_call_iter2; struct iter_call_s { INTERFACE(iter_conf); italgo_fun_t fun; iter_conf* _conf; }; #endif bart-0.5.00/src/iter/iter2.c000066400000000000000000000270561353046746100154720ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * 2014-2018 Jon Tamir * 2017 Sofia Dimoudi */ #include #include #include #include #include #include "misc/misc.h" #include "misc/types.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "num/ops_p.h" #include "num/ops.h" #include "linops/linop.h" #include "iter/italgos.h" #include "iter/iter.h" #include "iter/prox.h" #include "iter/admm.h" #include "iter/vec.h" #include "iter/niht.h" #include "iter2.h" void operator_iter(iter_op_data* _data, float* dst, const float* src) { auto data = CAST_DOWN(iter_op_op, _data); operator_apply_unchecked(data->op, (complex float*)dst, (const complex float*)src); } void operator_p_iter(iter_op_data* _data, float rho, float* dst, const float* src) { auto data = CAST_DOWN(iter_op_p_op, _data); operator_p_apply_unchecked(data->op, rho, (complex float*)dst, (const complex float*)src); } DEF_TYPEID(iter_op_op); DEF_TYPEID(iter_op_p_op); DEF_TYPEID(iter2_call_s); static bool checkeps(float eps) { if (0. == eps) { debug_printf(DP_WARN, "Warning: data empty\n"); return true; } if (!isnormal(eps)) { debug_printf(DP_WARN, "Warning: data corrupted\n"); return true; } return false; } static bool check_ops(long size, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D]) { if (NULL != normaleq_op) { auto dom = operator_domain(normaleq_op); if (size != 2 * md_calc_size(dom->N, dom->dims)) // FIXME: too weak return false; auto cod = operator_codomain(normaleq_op); if (size != 2 * md_calc_size(cod->N, cod->dims)) // FIXME: too weak return false; } for (unsigned int i = 0; i < D; i++) { long cosize = size; if ((NULL != ops) && (NULL != ops[i])) { auto dom = linop_domain(ops[i]); if (size != 2 * md_calc_size(dom->N, dom->dims)) // FIXME: too weak return false; auto cod = linop_codomain(ops[i]); cosize = 2 * md_calc_size(cod->N, cod->dims); } if ((NULL != prox_ops) && (NULL != prox_ops[i])) { auto dom2 = operator_p_domain(prox_ops[i]); if (cosize != 2 * md_calc_size(dom2->N, dom2->dims)) return false; // FIXME: too weak } } return true; } void iter2_conjgrad(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { assert(0 == D); assert(NULL == prox_ops); assert(NULL == ops); assert(NULL == biases); UNUSED(xupdate_op); assert(check_ops(size, normaleq_op, D, prox_ops, ops)); auto conf = CAST_DOWN(iter_conjgrad_conf, _conf); float eps = md_norm(1, MD_DIMS(size), image_adj); if (checkeps(eps)) goto cleanup; conjgrad(conf->maxiter, conf->INTERFACE.alpha * conf->l2lambda, eps * conf->tol, size, select_vecops(image_adj), OPERATOR2ITOP(normaleq_op), image, image_adj, monitor); cleanup: ; } void iter2_ist(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { assert(D == 1); assert(NULL != prox_ops[0]); assert(NULL == biases); #if 0 assert(NULL == ops); #else UNUSED(ops); #endif UNUSED(xupdate_op); assert(check_ops(size, normaleq_op, D, prox_ops, ops)); auto conf = CAST_DOWN(iter_ist_conf, _conf); float eps = md_norm(1, MD_DIMS(size), image_adj); if (checkeps(eps)) goto cleanup; // This was probably broken for IST until v0.4.04 // better turn of it off with an error assert(1 == conf->continuation); // Let's see whether somebody uses it... assert(!conf->hogwild); ist(conf->maxiter, eps * conf->tol, conf->INTERFACE.alpha * conf->step, size, select_vecops(image_adj), NULL, OPERATOR2ITOP(normaleq_op), OPERATOR_P2ITOP(prox_ops[0]), image, image_adj, monitor); cleanup: ; } void iter2_fista(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { assert(D == 1); assert(NULL == biases); #if 0 assert(NULL == ops); #else UNUSED(ops); #endif UNUSED(xupdate_op); auto conf = CAST_DOWN(iter_fista_conf, _conf); float eps = md_norm(1, MD_DIMS(size), image_adj); assert(check_ops(size, normaleq_op, D, prox_ops, ops)); if (checkeps(eps)) return; // clang limitation // goto cleanup; assert((conf->continuation >= 0.) && (conf->continuation <= 1.)); __block int hogwild_k = 0; __block int hogwild_K = 10; NESTED(void, continuation, (struct ist_data* itrdata)) { float a = logf(conf->continuation) / (float)itrdata->maxiter; itrdata->scale = expf(a * itrdata->iter); if (conf->hogwild) { /* this is not exactly identical to what was implemented * before as tau is now reduced at the beginning. But this * seems more correct. */ hogwild_k++; if (hogwild_k == hogwild_K) { hogwild_k = 0; hogwild_K *= 2; itrdata->tau /= 2; } } }; fista(conf->maxiter, eps * conf->tol, conf->INTERFACE.alpha * conf->step, size, select_vecops(image_adj), continuation, OPERATOR2ITOP(normaleq_op), OPERATOR_P2ITOP(prox_ops[0]), image, image_adj, monitor); // cleanup: ; } /* Chambolle Pock Primal Dual algorithm. Solves G(x) + F(Ax) * Assumes that G is in prox_ops[0], F is in prox_ops[1], A is in ops[1] */ void iter2_chambolle_pock(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { assert(D == 2); assert(NULL == biases); assert(NULL == normaleq_op); UNUSED(xupdate_op); UNUSED(image_adj); auto conf = CAST_DOWN(iter_chambolle_pock_conf, _conf); const struct iovec_s* iv = linop_domain(ops[1]); const struct iovec_s* ov = linop_codomain(ops[1]); assert((long)md_calc_size(iv->N, iv->dims) * 2 == size); assert(check_ops(size, normaleq_op, D, prox_ops, ops)); // FIXME: sensible way to check for corrupt data? #if 0 float eps = md_norm(1, MD_DIMS(size), image_adj); if (checkeps(eps)) goto cleanup; #else float eps = 1.; #endif // FIXME: conf->INTERFACE.alpha * c chambolle_pock(conf->maxiter, eps * conf->tol, conf->tau, conf->sigma, conf->theta, conf->decay, 2 * md_calc_size(iv->N, iv->dims), 2 * md_calc_size(ov->N, ov->dims), select_vecops(image), OPERATOR2ITOP(ops[1]->forward), OPERATOR2ITOP(ops[1]->adjoint), OPERATOR_P2ITOP(prox_ops[1]), OPERATOR_P2ITOP(prox_ops[0]), image, monitor); //cleanup: //; } void iter2_admm(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { auto conf = CAST_DOWN(iter_admm_conf, _conf); assert(check_ops(size, normaleq_op, D, prox_ops, ops)); struct admm_plan_s admm_plan = { .maxiter = conf->maxiter, .maxitercg = conf->maxitercg, .cg_eps = conf->cg_eps, .rho = conf->rho, .num_funs = D, .do_warmstart = conf->do_warmstart, .dynamic_rho = conf->dynamic_rho, .dynamic_tau = conf->dynamic_tau, .relative_norm = conf->relative_norm, .hogwild = conf->hogwild, .ABSTOL = conf->ABSTOL, .RELTOL = conf->RELTOL, .alpha = conf->alpha * conf->INTERFACE.alpha, .tau = conf->tau, .tau_max = conf->tau_max, .mu = conf->mu, .fast = conf->fast, .biases = biases, }; struct admm_op a_ops[D ?:1]; struct iter_op_p_s a_prox_ops[D ?:1]; for (unsigned int i = 0; i < D; i++) { a_ops[i].forward = OPERATOR2ITOP(ops[i]->forward), a_ops[i].normal = OPERATOR2ITOP(ops[i]->normal); a_ops[i].adjoint = OPERATOR2ITOP(ops[i]->adjoint); a_prox_ops[i] = OPERATOR_P2ITOP(prox_ops[i]); } admm_plan.ops = a_ops; admm_plan.prox_ops = a_prox_ops; admm_plan.xupdate = OPERATOR_P2ITOP(xupdate_op); long z_dims[D ?: 1]; for (unsigned int i = 0; i < D; i++) z_dims[i] = 2 * md_calc_size(linop_codomain(ops[i])->N, linop_codomain(ops[i])->dims); if (NULL != image_adj) { float eps = md_norm(1, MD_DIMS(size), image_adj); if (checkeps(eps)) goto cleanup; } admm(&admm_plan, admm_plan.num_funs, z_dims, size, (float*)image, image_adj, select_vecops(image), OPERATOR2ITOP(normaleq_op), monitor); cleanup: ; } void iter2_pocs(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { auto conf = CAST_DOWN(iter_pocs_conf, _conf); assert(NULL == normaleq_op); assert(NULL == ops); assert(NULL == biases); assert(NULL == image_adj); UNUSED(xupdate_op); UNUSED(image_adj); assert(check_ops(size, normaleq_op, D, prox_ops, ops)); struct iter_op_p_s proj_ops[D]; for (unsigned int i = 0; i < D; i++) proj_ops[i] = OPERATOR_P2ITOP(prox_ops[i]); pocs(conf->maxiter, D, proj_ops, select_vecops(image), size, image, monitor); } void iter2_niht(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { UNUSED(xupdate_op); UNUSED(biases); assert(D == 1); auto conf = CAST_DOWN(iter_niht_conf, _conf); struct niht_conf_s niht_conf = { .maxiter = conf->maxiter, .N = size, .trans = 0, .do_warmstart = conf->do_warmstart, }; struct niht_transop trans; if (NULL != ops) { trans.forward = OPERATOR2ITOP(ops[0]->forward); trans.adjoint = OPERATOR2ITOP(ops[0]->adjoint); trans.N = 2 * md_calc_size(linop_codomain(ops[0])->N, linop_codomain(ops[0])->dims); niht_conf.trans = 1; } float eps = md_norm(1, MD_DIMS(size), image_adj); if (checkeps(eps)) goto cleanup; niht_conf.epsilon = eps * conf->tol; niht(&niht_conf, &trans, select_vecops(image_adj), OPERATOR2ITOP(normaleq_op), OPERATOR_P2ITOP(prox_ops[0]), image, image_adj, monitor); cleanup: ; } void iter2_call_iter(iter_conf* _conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[D], const struct linop_s* ops[D], const float* biases[D], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor) { assert(D <= 1); assert(NULL == ops); assert(NULL == biases); UNUSED(xupdate_op); auto it = CAST_DOWN(iter_call_s, _conf); it->fun(it->_conf, normaleq_op, (1 == D) ? prox_ops[0] : NULL, size, image, image_adj, monitor); } bart-0.5.00/src/iter/iter2.h000066400000000000000000000043751353046746100154760ustar00rootroot00000000000000/* Copyright 2013-2017. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __ITER2_H #define __ITER2_H #include "misc/cppwrap.h" #include "misc/types.h" struct linop_s; struct operator_s; struct operator_p_s; #ifndef ITER_OP_DATA_S #define ITER_OP_DATA_S typedef struct iter_op_data_s { TYPEID* TYPEID; } iter_op_data; #endif struct iter_op_op { INTERFACE(iter_op_data); const struct operator_s* op; }; struct iter_op_p_op { INTERFACE(iter_op_data); const struct operator_p_s* op; }; extern void operator_iter(iter_op_data* data, float* dst, const float* src); extern void operator_p_iter(iter_op_data* data, float rho, float* dst, const float* src); // the temporay copy is needed if used in loops #define STRUCT_TMP_COPY(x) ({ __typeof(x) __foo = (x); __typeof(__foo)* __foo2 = alloca(sizeof(__foo)); *__foo2 = __foo; __foo2; }) #define OPERATOR2ITOP(op) (struct iter_op_s){ (NULL == op) ? NULL : operator_iter, CAST_UP(STRUCT_TMP_COPY(((struct iter_op_op){ { &TYPEID(iter_op_op) }, op }))) } #define OPERATOR_P2ITOP(op) (struct iter_op_p_s){ (NULL == op) ? NULL : operator_p_iter, CAST_UP(STRUCT_TMP_COPY(((struct iter_op_p_op){ { &TYPEID(iter_op_p_op) }, op }))) } #ifndef ITER_CONF_S #define ITER_CONF_S typedef struct iter_conf_s { TYPEID* TYPEID; float alpha; } iter_conf; #endif struct iter_monitor_s; typedef void (italgo_fun2_f)(iter_conf* conf, const struct operator_s* normaleq_op, unsigned int D, const struct operator_p_s* prox_ops[__VLA2(D)], const struct linop_s* ops[__VLA2(D)], const float* biases[__VLA2(D)], const struct operator_p_s* xupdate_op, long size, float* image, const float* image_adj, struct iter_monitor_s* monitor); typedef italgo_fun2_f* italgo_fun2_t; italgo_fun2_f iter2_conjgrad; italgo_fun2_f iter2_ist; italgo_fun2_f iter2_fista; italgo_fun2_f iter2_chambolle_pock; italgo_fun2_f iter2_admm; italgo_fun2_f iter2_pocs; italgo_fun2_f iter2_niht; // use with iter_call_s from iter.h as _conf italgo_fun2_f iter2_call_iter; struct iter2_call_s { INTERFACE(iter_conf); italgo_fun2_t fun; iter_conf* _conf; }; #include "misc/cppwrap.h" #endif bart-0.5.00/src/iter/iter3.c000066400000000000000000000017561353046746100154720ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "misc/types.h" #include "misc/misc.h" #include "iter/italgos.h" #include "iter/vec.h" #include "iter3.h" DEF_TYPEID(iter3_irgnm_conf); DEF_TYPEID(iter3_landweber_conf); const struct iter3_irgnm_conf iter3_irgnm_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter3_irgnm_conf), .iter = 8, .alpha = 1., .alpha_min = 0., .redu = 2., .cgiter = 100, .cgtol = 0.1, .nlinv_legacy = false, }; const struct iter3_landweber_conf iter3_landweber_defaults = { .INTERFACE.TYPEID = &TYPEID2(iter3_landweber_conf), .iter = 8, .alpha = 1., .epsilon = 0.1, }; bart-0.5.00/src/iter/iter3.h000066400000000000000000000013471353046746100154730ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/types.h" typedef struct iter3_conf_s { TYPEID* TYPEID; } iter3_conf; struct iter_op_s; struct iter3_irgnm_conf { INTERFACE(iter3_conf); int iter; float alpha; float alpha_min; float redu; int cgiter; float cgtol; _Bool nlinv_legacy; }; struct iter3_landweber_conf { INTERFACE(iter3_conf); int iter; float alpha; float epsilon; }; extern const struct iter3_irgnm_conf iter3_irgnm_defaults; extern const struct iter3_landweber_conf iter3_landweber_defaults; bart-0.5.00/src/iter/iter4.c000066400000000000000000000131511353046746100154630ustar00rootroot00000000000000/* Copyright 2017-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include #include "num/ops.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "nlops/nlop.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/debug.h" #include "iter/italgos.h" #include "iter/vec.h" #include "iter/iter3.h" #include "iter/iter2.h" #include "iter4.h" struct iter4_nlop_s { INTERFACE(iter_op_data); struct nlop_s nlop; }; DEF_TYPEID(iter4_nlop_s); static void nlop_for_iter(iter_op_data* _o, float* _dst, const float* _src) { const auto nlop = CAST_DOWN(iter4_nlop_s, _o); assert(2 == operator_nr_args(nlop->nlop.op)); operator_apply_unchecked(nlop->nlop.op, (complex float*)_dst, (const complex float*)_src); } static void nlop_der_iter(iter_op_data* _o, float* _dst, const float* _src) { const auto nlop = CAST_DOWN(iter4_nlop_s, _o); assert(2 == operator_nr_args(nlop->nlop.op)); linop_forward_unchecked(nlop->nlop.derivative[0], (complex float*)_dst, (const complex float*)_src); } static void nlop_adj_iter(iter_op_data* _o, float* _dst, const float* _src) { const auto nlop = CAST_DOWN(iter4_nlop_s, _o); assert(2 == operator_nr_args(nlop->nlop.op)); linop_adjoint_unchecked(nlop->nlop.derivative[0], (complex float*)_dst, (const complex float*)_src); } struct irgnm_s { INTERFACE(iter_op_data); struct iter_op_s der; struct iter_op_s adj; float* tmp; long size; int cgiter; float cgtol; bool nlinv_legacy; }; DEF_TYPEID(irgnm_s); static void normal(iter_op_data* _data, float* dst, const float* src) { auto data = CAST_DOWN(irgnm_s, _data); iter_op_call(data->der, data->tmp, src); iter_op_call(data->adj, dst, data->tmp); } static void inverse(iter_op_data* _data, float alpha, float* dst, const float* src) { auto data = CAST_DOWN(irgnm_s, _data); md_clear(1, MD_DIMS(data->size), dst, FL_SIZE); float eps = data->cgtol * md_norm(1, MD_DIMS(data->size), src); /* The original (Matlab) nlinv implementation uses * "sqrt(rsnew) < 0.01 * rsnot" as termination condition. */ if (data->nlinv_legacy) eps = powf(eps, 2.); conjgrad(data->cgiter, alpha, eps, data->size, select_vecops(src), (struct iter_op_s){ normal, CAST_UP(data) }, dst, src, NULL); } void iter4_irgnm(const iter3_conf* _conf, struct nlop_s* nlop, long N, float* dst, const float* ref, long M, const float* src, const struct operator_p_s* pinv, struct iter_op_s cb) { struct iter4_nlop_s data = { { &TYPEID(iter4_nlop_s) }, *nlop }; auto cd = nlop_codomain(nlop); auto dm = nlop_domain(nlop); assert(NULL == pinv); // better we allow this only with irgnm2 assert(M * sizeof(float) == md_calc_size(cd->N, cd->dims) * cd->size); assert(N * sizeof(float) == md_calc_size(dm->N, dm->dims) * dm->size); auto conf = CAST_DOWN(iter3_irgnm_conf, _conf); struct iter_op_s frw = { nlop_for_iter, CAST_UP(&data) }; struct iter_op_s der = { nlop_der_iter, CAST_UP(&data) }; struct iter_op_s adj = { nlop_adj_iter, CAST_UP(&data) }; float* tmp = md_alloc_sameplace(1, MD_DIMS(M), FL_SIZE, src); struct irgnm_s data2 = { { &TYPEID(irgnm_s) }, der, adj, tmp, N, conf->cgiter, conf->cgtol, conf->nlinv_legacy }; struct iter_op_p_s inv = { inverse, CAST_UP(&data2) }; irgnm(conf->iter, conf->alpha, conf->alpha_min, conf->redu, N, M, select_vecops(src), frw, adj, inv, dst, ref, src, cb, NULL); md_free(tmp); } void iter4_landweber(const iter3_conf* _conf, struct nlop_s* nlop, long N, float* dst, const float* ref, long M, const float* src, const struct operator_p_s* inv, struct iter_op_s cb) { assert(NULL == ref); assert(NULL == inv); struct iter4_nlop_s data = { { &TYPEID(iter4_nlop_s) }, *nlop }; auto conf = CAST_DOWN(iter3_landweber_conf, _conf); float* tmp = md_alloc_sameplace(1, MD_DIMS(N), FL_SIZE, src); struct iter_op_s frw = { nlop_for_iter, CAST_UP(&data) }; struct iter_op_s adj = { nlop_adj_iter, CAST_UP(&data) }; landweber(conf->iter, conf->epsilon, conf->alpha, N, M, select_vecops(src), frw, adj, dst, src, cb, NULL); md_free(tmp); } static void inverse2(iter_op_data* _data, float alpha, float* dst, const float* src) { auto data = CAST_DOWN(irgnm_s, _data); float* tmp = md_alloc_sameplace(1, MD_DIMS(data->size), FL_SIZE, src); iter_op_call(data->adj, tmp, src); inverse(_data, alpha, dst, tmp); md_free(tmp); } void iter4_irgnm2(const iter3_conf* _conf, struct nlop_s* nlop, long N, float* dst, const float* ref, long M, const float* src, const struct operator_p_s* lsqr, struct iter_op_s cb) { struct iter4_nlop_s data = { { &TYPEID(iter4_nlop_s) }, *nlop }; auto cd = nlop_codomain(nlop); auto dm = nlop_domain(nlop); assert(M * sizeof(float) == md_calc_size(cd->N, cd->dims) * cd->size); assert(N * sizeof(float) == md_calc_size(dm->N, dm->dims) * dm->size); auto conf = CAST_DOWN(iter3_irgnm_conf, _conf); float* tmp = md_alloc_sameplace(1, MD_DIMS(M), FL_SIZE, src); struct iter_op_s frw = { nlop_for_iter, CAST_UP(&data) }; struct iter_op_s der = { nlop_der_iter, CAST_UP(&data) }; struct iter_op_s adj = { nlop_adj_iter, CAST_UP(&data) }; struct irgnm_s data2 = { { &TYPEID(irgnm_s) }, der, adj, tmp, N, conf->cgiter, conf->cgtol, conf->nlinv_legacy }; // one limitation is that we currently cannot warm start the inner solver struct iter_op_p_s inv2 = { inverse2, CAST_UP(&data2) }; irgnm2(conf->iter, conf->alpha, conf->alpha_min, 0., conf->redu, N, M, select_vecops(src), frw, der, (NULL == lsqr) ? inv2 : OPERATOR_P2ITOP(lsqr), dst, ref, src, cb, NULL); md_free(tmp); } bart-0.5.00/src/iter/iter4.h000066400000000000000000000013461353046746100154730ustar00rootroot00000000000000/* Copyright 2017-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/types.h" struct operator_p_s; struct iter3_conf_s; struct iter_op_s; struct iter_nlop_s; struct nlop_s; typedef void iter4_fun_f(const struct iter3_conf_s* _conf, struct nlop_s* nlop, long N, float* dst, const float* ref, long M, const float* src, const struct operator_p_s* solve, const struct iter_op_s cb); iter4_fun_f iter4_irgnm; iter4_fun_f iter4_irgnm2; iter4_fun_f iter4_landweber; struct iter3_irgnm_conf; extern const struct iter3_irgnm_conf iter3_irgnm_defaults; extern const struct iter3_landweber_conf iter3_landweber_defaults; bart-0.5.00/src/iter/iter5.c000066400000000000000000000047511353046746100154720ustar00rootroot00000000000000/* Copyright 2017-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include "num/ops.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "nlops/nlop.h" #include "misc/misc.h" #include "misc/types.h" #include "iter/italgos.h" #include "iter/iter3.h" #include "iter/vec.h" #include "iter5.h" struct iter5_altmin_s { INTERFACE(iter_op_data); struct nlop_s* nlop; struct iter3_irgnm_conf* conf; long i; // argument to minimize }; DEF_TYPEID(iter5_altmin_s); static void altmin_nlop(iter_op_data* _o, int N, float* args[N]) { const auto data = CAST_DOWN(iter5_altmin_s, _o); assert((unsigned int)N == operator_nr_args(data->nlop->op)); nlop_generic_apply_unchecked(data->nlop, N, (void*)args); } static void altmin_normal(iter_op_data* _o, float* dst, const float* src) { const auto data = CAST_DOWN(iter5_altmin_s, _o); const struct linop_s* der = nlop_get_derivative(data->nlop, 0, data->i); linop_normal_unchecked(der, (complex float*)dst, (const complex float*)src); } static void altmin_inverse(iter_op_data* _o, float alpha, float* dst, const float* src) { const auto data = CAST_DOWN(iter5_altmin_s, _o); const struct iovec_s* idest = nlop_generic_domain(data->nlop, data->i); long size = 2 * md_calc_size(idest->N, idest->dims); float* AHy = md_alloc_sameplace(1, MD_DIMS(size), FL_SIZE, src); linop_adjoint_unchecked(nlop_get_derivative(data->nlop, 0, data->i), (complex float*)AHy, (const complex float*)src); float eps = data->conf->cgtol * md_norm(idest->N, idest->dims, AHy); conjgrad(data->conf->cgiter, alpha, eps, size, select_vecops(src), (struct iter_op_s){ altmin_normal, _o }, dst, AHy, NULL); md_free(AHy); } void iter5_altmin(iter3_conf* _conf, struct nlop_s* nlop, long NI, float* dst[NI], long M, const float* src, struct iter_nlop_s cb) { auto conf = CAST_DOWN(iter3_irgnm_conf, _conf); struct iter5_altmin_s data = { { &TYPEID(iter5_altmin_s) }, nlop, conf, -1 }; struct iter_op_p_s min_ops[NI]; struct iter5_altmin_s min_data[NI]; for(long i = 0; i < NI; ++i) { min_data[i] = (struct iter5_altmin_s){ { &TYPEID(iter4_altmin_s) }, nlop, conf, i }; min_ops[i] = (struct iter_op_p_s){ altmin_inverse, CAST_UP(&min_data[i]) }; } altmin(conf->iter, conf->alpha, conf->redu, M, select_vecops(src), NI, (struct iter_nlop_s){ altmin_nlop, CAST_UP(&data) }, min_ops, dst, src, cb); } bart-0.5.00/src/iter/iter5.h000066400000000000000000000003671353046746100154760ustar00rootroot00000000000000 struct iter3_conf_s; struct iter_nlop_s; struct nlop_s; typedef void iter5_altmin_f(iter3_conf* _conf, struct nlop_s* nlop, long NI, float* dst[NI], long M, const float* src, struct iter_nlop_s cb); iter5_altmin_f iter5_altmin; bart-0.5.00/src/iter/itop.c000066400000000000000000000100131353046746100154010ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016-2019 Martin Uecker * 2017 Jon Tamir */ #include #include "misc/misc.h" #include "misc/types.h" #include "num/multind.h" #include "num/ops.h" #include "num/ops_p.h" #include "num/iovec.h" #include "linops/linop.h" #include "iter/iter2.h" #include "itop.h" struct itop_s { INTERFACE(operator_data_t); italgo_fun2_t italgo; iter_conf* iconf; struct iter_monitor_s* monitor; const struct operator_s* op; unsigned int num_funs; long size; const struct iovec_s* iov; const float* init; const struct operator_p_s** prox_funs; const struct linop_s** prox_linops; }; static DEF_TYPEID(itop_s); static void itop_apply(const operator_data_t* _data, float alpha, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(itop_s, _data); if (NULL == data->init) { md_clear(1, MD_DIMS(data->size), dst, sizeof(float)); } else { md_copy(data->iov->N, data->iov->dims, dst, data->init, data->iov->size); } iter_conf* iconf2 = xmalloc(SIZEOF(data->iconf)); memcpy(iconf2, data->iconf, SIZEOF(data->iconf)); iconf2->alpha = alpha; data->italgo(iconf2, data->op, data->num_funs, data->prox_funs, data->prox_linops, NULL, NULL, data->size, (float*)dst, (const float*)src, data->monitor); xfree(iconf2); } static void itop_del(const operator_data_t* _data) { auto data = CAST_DOWN(itop_s, _data); iovec_free(data->iov); operator_free(data->op); if (NULL != data->init) md_free(data->init); if (NULL != data->prox_funs) { for (unsigned int i = 0; i < data->num_funs; i++) operator_p_free(data->prox_funs[i]); xfree(data->prox_funs); } if (NULL != data->prox_linops) { for (unsigned int i = 0; i < data->num_funs; i++) linop_free(data->prox_linops[i]); xfree(data->prox_linops); } xfree(data); } const struct operator_p_s* itop_p_create(italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct operator_s* op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], struct iter_monitor_s* monitor) { PTR_ALLOC(struct itop_s, data); SET_TYPEID(itop_s, data); const struct iovec_s* iov; if (NULL == op) { assert(0 < num_funs); iov = linop_domain(prox_linops[0]); } else { iov = operator_domain(op); } data->iconf = iconf; data->italgo = italgo; data->monitor = monitor; data->op = (NULL == op) ? NULL : operator_ref(op); data->num_funs = num_funs; data->size = 2 * md_calc_size(iov->N, iov->dims); // FIXME: do not assume complex data->prox_funs = NULL; data->prox_linops = NULL; data->init = NULL; data->iov = iovec_create(iov->N, iov->dims, iov->size); if (NULL != init) { float* init2 = md_alloc(iov->N, iov->dims, iov->size); md_copy(iov->N, iov->dims, init2, init, iov->size); data->init = init2; } if (NULL != prox_funs) { data->prox_funs = *TYPE_ALLOC(const struct operator_p_s*[num_funs]); for (unsigned int i = 0; i < num_funs; i++) data->prox_funs[i] = operator_p_ref(prox_funs[i]); } if (NULL != prox_linops) { data->prox_linops = *TYPE_ALLOC(const struct linop_s*[num_funs]); for (unsigned int i = 0; i < num_funs; i++) data->prox_linops[i] = linop_clone(prox_linops[i]); } return operator_p_create(iov->N, iov->dims, iov->N, iov->dims, CAST_UP(PTR_PASS(data)), itop_apply, itop_del); } const struct operator_s* itop_create( italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct operator_s* op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], struct iter_monitor_s* monitor) { return operator_p_bind(itop_p_create(italgo, iconf, init, op, num_funs, prox_funs, prox_linops, monitor), 1.); } bart-0.5.00/src/iter/itop.h000066400000000000000000000013341353046746100154140ustar00rootroot00000000000000 #include "iter/iter2.h" struct operator_s; struct operator_p_s; struct linop_s; struct iter_monitor_s; const struct operator_s* itop_create( italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct operator_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], struct iter_monitor_s* monitor); const struct operator_p_s* itop_p_create(italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct operator_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], struct iter_monitor_s* monitor); bart-0.5.00/src/iter/lad.c000066400000000000000000000116431353046746100152000ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2012-2018 Martin Uecker * 2014 Frank Ong */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops_p.h" #include "num/ops.h" #include "num/iovec.h" #include "linops/linop.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/types.h" #include "iter/iter.h" #include "iter/lsqr.h" #include "lad.h" const struct lad_conf lad_defaults = { 5, 0.1, ~0u, &lsqr_defaults }; /** * Perform iterative, regularized least-absolute derivation reconstruction. */ void lad2( unsigned int N, const struct lad_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], const long x_dims[static N], complex float* x, const long y_dims[static N], const complex float* y) { long w_dims[N]; md_select_dims(N, conf->wflags, w_dims, y_dims); complex float* weights = md_alloc_sameplace(N, w_dims, CFL_SIZE, y); complex float* tmp2 = md_alloc_sameplace(N, y_dims, CFL_SIZE, y); // use iterative reweigted least-squares // ADMM may be a better choice though... for (int i = 0; i < conf->rwiter; i++) { // recompute weights linop_forward(model_op, N, y_dims, tmp2, N, x_dims, x); md_zsub(N, y_dims, tmp2, tmp2, y); md_zrss(N, y_dims, ~(conf->wflags), weights, tmp2); for (long l = 0; l < md_calc_size(N, w_dims); l++) if (weights[l] != 0.) weights[l] = 1. / sqrtf(MAX(conf->gamma, cabsf(weights[l]))); // solve weighted least-squares wlsqr2(N, conf->lsqr_conf, italgo, iconf, model_op, 1, prox_funs, prox_linops, x_dims, x, y_dims, y, w_dims, weights, NULL); } md_free(tmp2); md_free(weights); } /** * Perform iterative, regularized least-absolute derivation reconstruction. */ void lad( unsigned int N, const struct lad_conf* conf, italgo_fun_t italgo, iter_conf* iconf, const struct linop_s* model_op, const struct operator_p_s* prox_funs, const long x_dims[static N], complex float* x, const long y_dims[static N], const complex float* y) { lad2(N, conf, iter2_call_iter, CAST_UP(&((struct iter_call_s){ { &TYPEID(iter_call_s), 1. }, italgo, iconf })), model_op, (NULL != prox_funs) ? 1 : 0, &prox_funs, NULL, x_dims, x, y_dims, y); } struct lad_s { INTERFACE(operator_data_t); const struct lad_conf* conf; italgo_fun2_t italgo; iter_conf* iconf; const struct linop_s* model_op; unsigned int num_funs; const struct operator_p_s** prox_funs; const struct linop_s** prox_linops; }; DEF_TYPEID(lad_s); static void lad_apply(const operator_data_t* _data, float alpha, complex float* dst, const complex float* src) { assert(1. == alpha); const auto data = CAST_DOWN(lad_s, _data); const struct iovec_s* dom_iov = operator_domain(data->model_op->forward); const struct iovec_s* cod_iov = operator_codomain(data->model_op->forward); lad2(dom_iov->N, data->conf, data->italgo, data->iconf, data->model_op, data->num_funs, data->prox_funs, data->prox_linops, cod_iov->dims, dst, dom_iov->dims, src); } static void lad_del(const operator_data_t* _data) { const auto data = CAST_DOWN(lad_s, _data); linop_free(data->model_op); if (NULL != data->prox_funs) { for (unsigned int i = 0; i < data->num_funs; i++) operator_p_free(data->prox_funs[i]); xfree(data->prox_funs); } if (NULL != data->prox_linops) { for (unsigned int i = 0; i < data->num_funs; i++) linop_free(data->prox_linops[i]); xfree(data->prox_linops); } xfree(data); } const struct operator_p_s* lad2_create(const struct lad_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs]) { PTR_ALLOC(struct lad_s, data); const struct iovec_s* dom_iov = operator_domain(model_op->forward); const struct iovec_s* cod_iov = operator_codomain(model_op->forward); assert(cod_iov->N == dom_iov->N); // this should be relaxed data->conf = conf; data->italgo = italgo; data->iconf = iconf; data->model_op = linop_clone(model_op); data->num_funs = num_funs; data->prox_funs = *TYPE_ALLOC(const struct operator_p_s*[num_funs]); data->prox_linops = *TYPE_ALLOC(const struct linop_s*[num_funs]); assert(NULL == init); for (unsigned int i = 0; i < num_funs; i++) { data->prox_funs[i] = operator_p_ref(prox_funs[i]); data->prox_linops[i] = linop_clone(prox_linops[i]); } return operator_p_create(cod_iov->N, cod_iov->dims, dom_iov->N, dom_iov->dims, CAST_UP(PTR_PASS(data)), lad_apply, lad_del); } bart-0.5.00/src/iter/lad.h000066400000000000000000000020301353046746100151730ustar00rootroot00000000000000 struct lsqr_conf; struct lad_conf { int rwiter; float gamma; unsigned int wflags; const struct lsqr_conf* lsqr_conf; }; extern void lad(unsigned int N, const struct lad_conf* conf, italgo_fun_t italgo, iter_conf* iconf, const struct linop_s* model_op, const struct operator_p_s* thresh_op, const long x_dims[N], complex float* x, const long y_dims[N], const complex float* y); extern void lad2(unsigned int N, const struct lad_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* thresh_op[num_funs], const struct linop_s* thresh_funs[num_funs], const long x_dims[N], complex float* x, const long y_dims[N], const complex float* y); extern const struct operator_p_s* lad2_create(const struct lad_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* thresh_op[num_funs], const struct linop_s* thresh_funs[num_funs]); bart-0.5.00/src/iter/lsqr.c000066400000000000000000000167501353046746100154250ustar00rootroot00000000000000/* Copyright 2014,2017. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2012-2018 Martin Uecker * 2014 Frank Ong * 2014,2017 Jon Tamir */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops_p.h" #include "num/ops.h" #include "num/iovec.h" #include "linops/linop.h" #include "linops/someops.h" #include "misc/debug.h" #include "misc/types.h" #include "misc/misc.h" #include "iter/iter.h" #include "iter/iter2.h" #include "iter/itop.h" #include "lsqr.h" const struct lsqr_conf lsqr_defaults = { .lambda = 0., .it_gpu = false }; struct lsqr_data { INTERFACE(operator_data_t); float l2_lambda; long size; const struct linop_s* model_op; }; static DEF_TYPEID(lsqr_data); static void normaleq_l2_apply(const operator_data_t* _data, unsigned int N, void* args[static N]) { const auto data = CAST_DOWN(lsqr_data, _data); assert(2 == N); linop_normal_unchecked(data->model_op, args[0], args[1]); md_axpy(1, MD_DIMS(data->size), args[0], data->l2_lambda, args[1]); } static void normaleq_del(const operator_data_t* _data) { const auto data = CAST_DOWN(lsqr_data, _data); linop_free(data->model_op); xfree(data); } /** * Operator for iterative, multi-regularized least-squares reconstruction */ const struct operator_p_s* lsqr2_create(const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct linop_s* model_op, const struct operator_s* precond_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], struct iter_monitor_s* monitor) { PTR_ALLOC(struct lsqr_data, data); SET_TYPEID(lsqr_data, data); const struct iovec_s* iov = NULL; if (NULL == model_op) { assert(0 < num_funs); iov = linop_domain(prox_linops[0]); data->model_op = NULL; } else { iov = operator_domain(model_op->forward); data->model_op = linop_clone(model_op); } data->l2_lambda = conf->lambda; data->size = 2 * md_calc_size(iov->N, iov->dims); // FIXME: assume complex const struct operator_s* normaleq_op = NULL; const struct operator_s* adjoint = NULL; if (NULL != model_op) { normaleq_op = operator_create(iov->N, iov->dims, iov->N, iov->dims, CAST_UP(PTR_PASS(data)), normaleq_l2_apply, normaleq_del); adjoint = operator_ref(model_op->adjoint); } else { PTR_FREE(data); } if (NULL != precond_op) { const struct operator_s* tmp; tmp = normaleq_op; normaleq_op = operator_chain(normaleq_op, precond_op); operator_free(tmp); tmp = adjoint; adjoint = operator_chain(adjoint, precond_op); operator_free(tmp); } const struct operator_p_s* itop_op = itop_p_create(italgo, iconf, init, normaleq_op, num_funs, prox_funs, prox_linops, monitor); if (conf->it_gpu) { debug_printf(DP_DEBUG1, "lsqr: add GPU wrapper\n"); itop_op = operator_p_gpu_wrapper(itop_op); } const struct operator_p_s* lsqr_op; if (NULL != adjoint) lsqr_op = operator_p_pre_chain(adjoint, itop_op); else lsqr_op = operator_p_ref(itop_op); operator_free(normaleq_op); operator_p_free(itop_op); operator_free(adjoint); return lsqr_op; } /** * Perform iterative, multi-regularized least-squares reconstruction */ void lsqr2(unsigned int N, const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], const long x_dims[static N], complex float* x, const long y_dims[static N], const complex float* y, const struct operator_s* precond_op, struct iter_monitor_s* monitor) { // nicer, but is still missing some features const struct operator_p_s* op = lsqr2_create(conf, italgo, iconf, NULL, model_op, precond_op, num_funs, prox_funs, prox_linops, monitor); operator_p_apply(op, 1., N, x_dims, x, N, y_dims, y); operator_p_free(op); } /** * Perform iterative, regularized least-squares reconstruction. */ void lsqr(unsigned int N, const struct lsqr_conf* conf, italgo_fun_t italgo, iter_conf* iconf, const struct linop_s* model_op, const struct operator_p_s* thresh_op, const long x_dims[static N], complex float* x, const long y_dims[static N], const complex float* y, const struct operator_s* precond_op) { lsqr2(N, conf, iter2_call_iter, CAST_UP(&((struct iter_call_s){ { &TYPEID(iter_call_s), 1. }, italgo, iconf })), model_op, (NULL != thresh_op) ? 1 : 0, &thresh_op, NULL, x_dims, x, y_dims, y, precond_op, NULL); } const struct operator_p_s* wlsqr2_create(const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct linop_s* model_op, const struct linop_s* weights, const struct operator_s* precond_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], struct iter_monitor_s* monitor) { struct linop_s* op = linop_chain(model_op, weights); linop_free(model_op); const struct operator_p_s* lsqr_op = lsqr2_create(conf, italgo, iconf, init, op, precond_op, num_funs, prox_funs, prox_linops, monitor); const struct operator_p_s* wlsqr_op = operator_p_pre_chain(weights->forward, lsqr_op); linop_free(weights); operator_p_free(lsqr_op); linop_free(op); return wlsqr_op; } void wlsqr2(unsigned int N, const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[num_funs], const struct linop_s* prox_linops[num_funs], const long x_dims[static N], complex float* x, const long y_dims[static N], const complex float* y, const long w_dims[static N], const complex float* w, const struct operator_s* precond_op) { unsigned int flags = 0; for (unsigned int i = 0; i < N; i++) if (1 < w_dims[i]) flags = MD_SET(flags, i); struct linop_s* weights = linop_cdiag_create(N, y_dims, flags, w); #if 1 struct linop_s* op = linop_chain(model_op, weights); complex float* wy = md_alloc_sameplace(N, y_dims, CFL_SIZE, y); linop_forward(weights, N, y_dims, wy, N, y_dims, y); lsqr2(N, conf, italgo, iconf, op, num_funs, prox_funs, prox_linops, x_dims, x, y_dims, wy, precond_op, NULL); md_free(wy); linop_free(op); #else const struct operator_s* op = wlsqr2_create(conf, italgo, iconf, model_op, weights, precond_op, num_funs, prox_funs, prox_linops); operator_apply(op, N, x_dims, x, N, y_dims, y); #endif linop_free(weights); } // A^H W W A - A^H W W y void wlsqr(unsigned int N, const struct lsqr_conf* conf, italgo_fun_t italgo, iter_conf* iconf, const struct linop_s* model_op, const struct operator_p_s* thresh_op, const long x_dims[static N], complex float* x, const long y_dims[static N], const complex float* y, const long w_dims[static N], const complex float* w, const struct operator_s* precond_op) { wlsqr2(N, conf, iter2_call_iter, CAST_UP(&((struct iter_call_s){ { &TYPEID(iter_call_s), 1. }, italgo, iconf })), model_op, (NULL != thresh_op) ? 1 : 0, &thresh_op, NULL, x_dims, x, y_dims, y, w_dims, w, precond_op); } bart-0.5.00/src/iter/lsqr.h000066400000000000000000000060511353046746100154230ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __LSQR_H #define __LSQR_H 1 #include "iter/iter.h" #include "iter/iter2.h" #include "misc/cppwrap.h" struct operator_s; struct operator_p_s; struct lsqr_conf { float lambda; _Bool it_gpu; }; struct iter_monitor_s; extern const struct lsqr_conf lsqr_defaults; extern const struct operator_p_s* lsqr2_create(const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct linop_s* model_op, const struct operator_s* precond_op, unsigned int num_funs, const struct operator_p_s* prox_funs[__VLA2(num_funs)], const struct linop_s* prox_linops[__VLA2(num_funs)], struct iter_monitor_s* monitor); extern const struct operator_p_s* wlsqr2_create(const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const float* init, const struct linop_s* model_op, const struct linop_s* weights, const struct operator_s* precond_op, unsigned int num_funs, const struct operator_p_s* prox_funs[__VLA2(num_funs)], const struct linop_s* prox_linops[__VLA2(num_funs)], struct iter_monitor_s* monitor); extern void lsqr( unsigned int N, const struct lsqr_conf* conf, italgo_fun_t italgo, iter_conf* iconf, const struct linop_s* model_op, const struct operator_p_s* thresh_op, const long x_dims[__VLA(N)], _Complex float* x, const long y_dims[__VLA(N)], const _Complex float* y, const struct operator_s* precond_op); extern void wlsqr( unsigned int N, const struct lsqr_conf* conf, italgo_fun_t italgo, iter_conf* iconf, const struct linop_s* model_op, const struct operator_p_s* thresh_op, const long x_dims[__VLA(N)], _Complex float* x, const long y_dims[__VLA(N)], const _Complex float* y, const long w_dims[__VLA(N)], const _Complex float* w, const struct operator_s* precond_op); extern void lsqr2( unsigned int N, const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[__VLA2(num_funs)], const struct linop_s* prox_linops[__VLA2(num_funs)], const long x_dims[__VLA(N)], _Complex float* x, const long y_dims[__VLA(N)], const _Complex float* y, const struct operator_s* precond_op, struct iter_monitor_s* monitor); extern void wlsqr2( unsigned int N, const struct lsqr_conf* conf, italgo_fun2_t italgo, iter_conf* iconf, const struct linop_s* model_op, unsigned int num_funs, const struct operator_p_s* prox_funs[__VLA2(num_funs)], const struct linop_s* prox_linops[__VLA2(num_funs)], const long x_dims[__VLA(N)], complex float* x, const long y_dims[__VLA(N)], const complex float* y, const long w_dims[__VLA(N)], const complex float* w, const struct operator_s* precond_op); #include "misc/cppwrap.h" #endif bart-0.5.00/src/iter/misc.c000066400000000000000000000025601353046746100153710ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong * 2015 Martin Uecker */ #include "num/multind.h" #include "num/ops.h" #include "num/iovec.h" #include "num/rand.h" #include "misc/misc.h" #include "iter/italgos.h" #include "iter/iter2.h" #include "iter/vec.h" #include "misc.h" double iter_power(unsigned int maxiter, const struct operator_s* normaleq_op, long size, float* u) { return power(maxiter, size, select_vecops(u), OPERATOR2ITOP(normaleq_op), u); } double estimate_maxeigenval(const struct operator_s* op) { const struct iovec_s* io = operator_domain(op); long size = md_calc_size(io->N, io->dims); void* x = md_alloc(io->N, io->dims, io->size); md_gaussian_rand(io->N, io->dims, x); double max_eval = iter_power(30, op, 2 * size, x); md_free(x); return max_eval; } #ifdef USE_CUDA double estimate_maxeigenval_gpu(const struct operator_s* op) { const struct iovec_s* io = operator_domain(op); long size = md_calc_size(io->N, io->dims); void* x = md_alloc_gpu(io->N, io->dims, io->size); md_gaussian_rand(io->N, io->dims, x); double max_eval = iter_power(30, op, 2 * size, x); md_free(x); return max_eval; } #endif bart-0.5.00/src/iter/misc.h000066400000000000000000000007141353046746100153750ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ struct operator_s; extern double iter_power(unsigned int maxiter, const struct operator_s* normaleq_op, long size, float* u); extern double estimate_maxeigenval(const struct operator_s* op); extern double estimate_maxeigenval_gpu(const struct operator_s* op); bart-0.5.00/src/iter/monitor.c000066400000000000000000000043301353046746100161220ustar00rootroot00000000000000/* Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016,2018 Martin Uecker */ #include #include "misc/debug.h" #include "misc/types.h" #include "misc/misc.h" #include "iter/vec.h" #include "monitor.h" void iter_monitor(struct iter_monitor_s* monitor, const struct vec_iter_s* ops, const float* x) { if ((NULL != monitor) && (NULL != monitor->fun)) monitor->fun(monitor, ops, x); } void iter_history(struct iter_monitor_s* monitor, const struct iter_history_s* hist) { if ((NULL != monitor) && (NULL != monitor->record)) monitor->record(monitor, hist); } struct monitor_default_s { INTERFACE(iter_monitor_t); long N; const float* image_truth; double it_norm; void* data; float (*objective)(const void* data, const float* x); }; static DEF_TYPEID(monitor_default_s); static void monitor_default_fun(struct iter_monitor_s* _data, const struct vec_iter_s* vops, const float* x) { static unsigned int iter = 0; auto data = CAST_DOWN(monitor_default_s, _data); double err = -1.; double obj = -1.; long N = data->N; if (NULL != data->image_truth) { if (-1. == data->it_norm) data->it_norm = vops->norm(N, data->image_truth); float* x_err = vops->allocate(N); vops->sub(N, x_err, data->image_truth, x); err = vops->norm(N, x_err) / data->it_norm; vops->del(x_err); } if (NULL != data->objective) obj = data->objective(data->data, x); debug_printf(DP_INFO, "[Iter %04d] Objective: %f, Error: %f\n", ++iter, obj, err); data->INTERFACE.obj = obj; data->INTERFACE.err = err; } struct iter_monitor_s* create_monitor(long N, const float* image_truth, void* data, float (*objective)(const void* data, const float* x)) { PTR_ALLOC(struct monitor_default_s, monitor); SET_TYPEID(monitor_default_s, monitor); monitor->N = N; monitor->image_truth = image_truth; monitor->it_norm = -1.; monitor->data = data; monitor->objective = objective; monitor->INTERFACE.fun = monitor_default_fun; monitor->INTERFACE.record = NULL; monitor->INTERFACE.obj = -1.; monitor->INTERFACE.err = -1.; return CAST_UP(PTR_PASS(monitor)); } bart-0.5.00/src/iter/monitor.h000066400000000000000000000017261353046746100161350ustar00rootroot00000000000000 #ifndef __ITER_MONITOR_H #define __ITER_MONITOR_H struct iter_monitor_s; struct vec_iter_s; struct typeid_s; struct iter_history_s { const struct typeid_s* TYPEID; }; typedef struct iter_history_s iter_history_t; typedef void (*iter_monitor_fun_t)(struct iter_monitor_s* data, const struct vec_iter_s* ops, const float* x); typedef void (*iter_history_fun_t)(struct iter_monitor_s* data, const struct iter_history_s*); struct iter_monitor_s { const struct typeid_s* TYPEID; iter_monitor_fun_t fun; iter_history_fun_t record; double obj; double err; }; typedef struct iter_monitor_s iter_monitor_t; extern void iter_monitor(struct iter_monitor_s* monitor, const struct vec_iter_s* ops, const float* x); extern void iter_history(struct iter_monitor_s* monitor, const struct iter_history_s*); extern struct iter_monitor_s* create_monitor(long N, const float* image_truth, void* data, float (*object)(const void* data, const float* x)); #endif // __ITER_MONITOR_H bart-0.5.00/src/iter/niht.c000066400000000000000000000175211353046746100154030ustar00rootroot00000000000000/* Copyright 2014-2016. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Sofia Dimoudi * * * * Blumensath T, Davies ME. Normalized iterative hard thresholding: Guaranteed * stability and performance. * IEEE Journal of selected topics in signal processing. 2010;4:298-309. * * Blanchard JD, Tanner J. Performance comparisons of greedy algorithms in * compressed sensing. * Numerical Linear Algebra with Applications. 2015;22:254-82. * */ #include #include #include #include #include "num/ops.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/types.h" #include "iter/italgos.h" #include "iter/vec.h" #include "iter/monitor.h" #include "niht.h" static void niht_imdom(const struct niht_conf_s* conf, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor) { double rsnew = 1.; // current residual double rsnot = 1.; // initial residual double rsold = 1.; // previous residual float mu = 1.; // step size unsigned int ic = 0; // iteration counter for criterion 3 unsigned int iter = 0; long N = conf->N; float* r = vops->allocate(N); float* g = vops->allocate(N); // negative gradient of ||y - Ax||^2 with non-zero support float* m = vops->allocate(N); // non-zero support mask rsnot = vops->norm(N, b); // initial residual norm rsold = rsnot; // create initial support if (!conf->do_warmstart) { //x_0 = 0, take support from b iter_op_p_call(thresh, 1.0, m, b); vops->zmul(N / 2, (complex float*)x, (complex float*)b, (complex float*)m); } else { // x_0 has an initial value, take support from x iter_op_p_call(thresh, 1.0, m, x); vops->zmul(N / 2, (complex float*)x, (complex float*)x, (complex float*)m); } for (iter = 0; iter < conf->maxiter; iter++) { iter_monitor(monitor, vops, x); iter_op_call(op, r, x); // r = A x vops->xpay(N, -1., r, b); // r = b - r = b - A x. // calculate step size. // 1. apply support x->g vops->zmul(N / 2, (complex float*)g, (complex float*)r, (complex float*)m); //mu = ||g_n||^2 / ||A g_n||^2 double num = vops->dot(N, g, g); iter_op_call(op, g, g); double den = vops->dot(N, g, g); mu = num / den; //step size rsnew = vops->norm(N, r); debug_printf(DP_DEBUG3, "\n#It %03d relative residual r / r_0: %f \n", iter, rsnew / rsnot); // Stopping criteria: Blanchard and Tanner 2015 // TODO: select appropriate epsilon and other criteria values if (rsnew < conf->epsilon) // residual is small break; if (rsnew > 100.0 * rsnot) // algorithm is diverging r_l > 100*r_0 break; if (fabs(rsnew - rsold) <= 1.0E-06f) { // no significant change in residual debug_printf(DP_INFO, "\n*** rsnew - rsold = %f **\n", fabs(rsnew - rsold) ); ic++; if (15 == ic) // in 16 iterations. Normally 1e-06 break; // more appropriate for noisy measurements } // where convergence will occur with larger residual vops->axpy(N, x, mu, r); // update solution: xk+1 = xk + mu rk+1 iter_op_p_call(thresh, 1.0, m, x); // apply thresholding Hs(xk+1) vops->zmul(N / 2, (complex float*)x, (complex float*)x, (complex float*)m); rsold = rsnew; // keep residual for comparison } debug_printf(DP_DEBUG3, "\n"); debug_printf(DP_DEBUG2, "\n#absolute residual: %f\n", rsnew); debug_printf(DP_DEBUG2, "\n#relative signal residual: %f\n\n", rsnew / rsnot); vops->del(r); vops->del(g); vops->del(m); } /** * Normalised Iterative Hard Thresholding/NIHT to solve min || b - Ax ||_2 s.t. || T x ||_0 <= k * using an adaptive step size with the iteration: x_n+1 = H_k (x_n + mu_n(A^T (y - A x_n)) * where H_k(x) = support(x) the hard thresholding operator, keeps the k largest elements of x * mu_n the adaptive step size. * * @param conf configuration params, eg maxiter, epsilon * @param trans linear transform operator, eg wavelets * @param vops vector ops definition * @param op linear operator, e.g. A * @param thresh NIHT threshold function * @param x initial estimate * @param b observations * @param monitor compute objective value, errors, etc. */ void niht(const struct niht_conf_s* conf, const struct niht_transop* trans, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor) { if (0 == conf->trans) { // do NIHT in image domain niht_imdom(conf, vops, op, thresh, x, b, monitor); return; } double rsnew = 1.; // current residual double rsnot = 1.; // initial residual double rsold = 1.; // previous residual float mu = 1.; // step size unsigned int ic = 0; // iteration counter for criterion 3 unsigned int iter = 0; long N = conf->N; long WN = trans->N; float* r = vops->allocate(N); float* g = vops->allocate(N); // negative gradient of ||y - Ax||^2 with non-zero support float* wg = vops->allocate(WN); // wavelet transform of g float* wx = vops->allocate(WN); // wavelet transform of x float* wm = vops->allocate(WN); // nonzero support mask with wavelet dimensions rsnot = vops->norm(N, b); // initial residual norm rsold = rsnot; // create initial support if (!conf->do_warmstart) { //x_0 = 0, take support from b iter_op_call(trans->forward, wx, b); iter_op_p_call(thresh, 1.0, wm, wx); //produce mask by thresholding vops->zmul(WN / 2, (complex float*)wx, (complex float*)wx, (complex float*)wm); // apply mask } else { // x_0 has an initial value, take support from x iter_op_call(trans->forward, wx, x); iter_op_p_call(thresh, 1.0, wm, wx); vops->zmul(WN / 2, (complex float*)wx, (complex float*)wx, (complex float*)wm); } iter_op_call(trans->adjoint, x, wx); for (iter = 0; iter < conf->maxiter; iter++) { iter_monitor(monitor, vops, x); iter_op_call(op, r, x); // r = A x vops->xpay(N, -1., r, b); // r = b - r = b - A x. // calculate step size. // 1. apply support x->g iter_op_call(trans->forward, wg, r); vops->zmul(WN / 2, (complex float*)wg, (complex float*)wg, (complex float*)wm); iter_op_call(trans->adjoint, g, wg); // 2. mu = ||g_n||^2 / ||A g_n||^2 double num = vops->dot(N, g, g); iter_op_call(op, g, g); double den = vops->dot(N, g, g); mu = num / den; debug_printf(DP_DEBUG3, "\n#step size: %f\n", mu); rsnew = vops->norm(N, r); debug_printf(DP_DEBUG3, "\n#It %03d relative residual r / r_0: %f \n", iter, rsnew / rsnot); // Stopping criteria: Blanchard and Tanner 2015 if (rsnew < conf->epsilon) // residual is small break; if (rsnew > 100.0 * rsnot) // algorithm is diverging r_l > 100*r_0 break; if (fabs(rsnew - rsold) <= 1.0E-06f) { // no significant change in residual debug_printf(DP_INFO, "\n*** rsnew - rsold = %f **\n", fabs(rsnew - rsold)); ic++; if (15 == ic) // in 16 iterations. Normally 1e-06 break; // more appropriate for noisy measurements } // where convergence will occur with larger residual vops->axpy(N, x, mu, r); // update solution: xk+1 = xk + mu rk+1 iter_op_call(trans->forward, wx, x); iter_op_p_call(thresh, 1.0, wm, wx); // apply thresholding Hs(xk+1) vops->zmul(WN / 2, (complex float*)wx, (complex float*)wx, (complex float*)wm); iter_op_call(trans->adjoint, x, wx); rsold = rsnew; // keep residual for comparison } debug_printf(DP_DEBUG3, "\n"); debug_printf(DP_DEBUG2, "\n#absolute residual: %f\n", rsnew); debug_printf(DP_DEBUG2, "\n#relative signal residual: %f\n\n", rsnew / rsnot); vops->del(r); vops->del(g); vops->del(wg); vops->del(wx); vops->del(wm); } bart-0.5.00/src/iter/niht.h000066400000000000000000000023201353046746100153770ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __NIHT_H #define __NIHT_H /** * struct containing linear transform operator for NIHT (e.g. wavelets) * * @param forward the forward transform operator * @param adjoint the adjoint transform operator * @param N length of transform vector in floats */ struct niht_transop { struct iter_op_s forward; struct iter_op_s adjoint; long N; }; /** * Store information about NIHT algorithm configuration. * * @param maxiter maximum iteration * @param epsilon stopping criterion * @param N length of image vector in floats * @param trans flag for use of transform (0/1) * @param do_warmstart flag for initial x vector */ struct niht_conf_s { unsigned int maxiter; float epsilon; long N; int trans; _Bool do_warmstart; }; void niht(const struct niht_conf_s* conf, const struct niht_transop* trans, const struct vec_iter_s* vops, struct iter_op_s op, struct iter_op_p_s thresh, float* x, const float* b, struct iter_monitor_s* monitor); #endif // __NIHT_H bart-0.5.00/src/iter/prox.c000066400000000000000000000452001353046746100154240ustar00rootroot00000000000000/* Copyright 2014-2017. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2017 Jon Tamir * 2016-2019 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops_p.h" #include "num/ops.h" #include "num/iovec.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "linops/linop.h" #include "iter/iter.h" #include "misc/misc.h" #include "prox.h" /** * Proximal function of f is defined as * (prox_f)(z) = arg min_x 0.5 || z - x ||_2^2 + f(x) * * (prox_{mu f})(z) = arg min_x 0.5 || z - x ||_2^2 + mu f(x) */ /** * Data for computing prox_normaleq_fun: * Proximal function for f(z) = 0.5 || y - A z ||_2^2. * * @param op operator that applies A^H A * @param cgconf conf file for conjugate gradient iter interface * @param adj A^H y * @param size size of z */ struct prox_normaleq_data { INTERFACE(operator_data_t); const struct linop_s* op; void* cgconf; float* adj; long size; }; static DEF_TYPEID(prox_normaleq_data); /** * Proximal function for f(z) = 0.5 || y - A z ||_2^2. * Solution is (A^H A + (1/mu) I)z = A^H y + (1/mu)(x_plus_u) * * @param prox_data should be of type prox_normaleq_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_normaleq_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { auto pdata = CAST_DOWN(prox_normaleq_data, prox_data); if (0 == mu) { md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE); } else { float rho = 1. / mu; float* b = md_alloc_sameplace(1, MD_DIMS(pdata->size), FL_SIZE, x_plus_u); md_copy(1, MD_DIMS(pdata->size), b, pdata->adj, FL_SIZE); md_axpy(1, MD_DIMS(pdata->size), b, rho, x_plus_u); if (NULL == pdata->op->norm_inv) { struct iter_conjgrad_conf* cg_conf = pdata->cgconf; cg_conf->l2lambda = rho; iter_conjgrad(CAST_UP(cg_conf), pdata->op->normal, NULL, pdata->size, z, (float*)b, NULL); } else { linop_norm_inv_unchecked(pdata->op, rho, (complex float*)z, (const complex float*)b); } md_free(b); } } static void prox_normaleq_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { prox_normaleq_fun(_data, mu, (float*)dst, (const float*)src); } static void prox_normaleq_del(const operator_data_t* _data) { auto pdata = CAST_DOWN(prox_normaleq_data, _data); xfree(pdata->cgconf); md_free(pdata->adj); xfree(pdata); } const struct operator_p_s* prox_normaleq_create(const struct linop_s* op, const complex float* y) { PTR_ALLOC(struct prox_normaleq_data, pdata); SET_TYPEID(prox_normaleq_data, pdata); PTR_ALLOC(struct iter_conjgrad_conf, cgconf); *cgconf = iter_conjgrad_defaults; cgconf->maxiter = 10; cgconf->l2lambda = 0; pdata->cgconf = PTR_PASS(cgconf); pdata->op = op; pdata->size = 2 * md_calc_size(linop_domain(op)->N, linop_domain(op)->dims); pdata->adj = md_alloc_sameplace(1, &(pdata->size), FL_SIZE, y); linop_adjoint_unchecked(op, (complex float*)pdata->adj, y); return operator_p_create(linop_domain(op)->N, linop_domain(op)->dims, linop_domain(op)->N, linop_domain(op)->dims, CAST_UP(PTR_PASS(pdata)), prox_normaleq_apply, prox_normaleq_del); } /** * Data for computing prox_leastsquares_fun: * Proximal function for f(z) = lambda / 2 || y - z ||_2^2. * * @param y * @param lambda regularization * @param size size of z */ struct prox_leastsquares_data { INTERFACE(operator_data_t); const float* y; float lambda; long size; }; static DEF_TYPEID(prox_leastsquares_data); /** * Proximal function for f(z) = lambda / 2 || y - z ||_2^2. * Solution is z = (mu * lambda * y + x_plus_u) / (mu * lambda + 1) * * @param prox_data should be of type prox_leastsquares_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_leastsquares_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { auto pdata = CAST_DOWN(prox_leastsquares_data, prox_data); md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE); if (0 != mu) { if (NULL != pdata->y) md_axpy(1, MD_DIMS(pdata->size), z, pdata->lambda * mu, pdata->y); md_smul(1, MD_DIMS(pdata->size), z, z, 1. / (mu * pdata->lambda + 1)); } } static void prox_leastsquares_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { prox_leastsquares_fun(_data, mu, (float*)dst, (const float*)src); } static void prox_leastsquares_del(const operator_data_t* _data) { xfree(CAST_DOWN(prox_leastsquares_data, _data)); } const struct operator_p_s* prox_leastsquares_create(unsigned int N, const long dims[N], float lambda, const complex float* y) { PTR_ALLOC(struct prox_leastsquares_data, pdata); SET_TYPEID(prox_leastsquares_data, pdata); pdata->y = (const float*)y; pdata->lambda = lambda; pdata->size = md_calc_size(N, dims) * 2; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_leastsquares_apply, prox_leastsquares_del); } /** * Data for computing prox_l2norm_fun: * Proximal function for f(z) = lambda || z ||_2. * * @param lambda regularization * @param size size of z */ struct prox_l2norm_data { INTERFACE(operator_data_t); float lambda; long size; }; static DEF_TYPEID(prox_l2norm_data); /** * Proximal function for f(z) = lambda || z ||_2. * Solution is z = ( 1 - lambda * mu / norm(z) )_+ * z, * i.e. block soft thresholding * * @param prox_data should be of type prox_l2norm_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_l2norm_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { auto pdata = CAST_DOWN(prox_l2norm_data, prox_data); md_clear(1, MD_DIMS(pdata->size), z, FL_SIZE); double q1 = md_norm(1, MD_DIMS(pdata->size), x_plus_u); if (q1 != 0) { double q2 = 1 - pdata->lambda * mu / q1; if (q2 > 0.) md_smul(1, MD_DIMS(pdata->size), z, x_plus_u, q2); } } static void prox_l2norm_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { prox_l2norm_fun(_data, mu, (float*)dst, (const float*)src); } static void prox_l2norm_del(const operator_data_t* _data) { xfree(CAST_DOWN(prox_l2norm_data, _data)); } const struct operator_p_s* prox_l2norm_create(unsigned int N, const long dims[N], float lambda) { PTR_ALLOC(struct prox_l2norm_data, pdata); SET_TYPEID(prox_l2norm_data, pdata); pdata->lambda = lambda; pdata->size = md_calc_size(N, dims) * 2; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_l2norm_apply, prox_l2norm_del); } /** * Data for computing prox_l2ball_fun: * Proximal function for f(z) = Ind{ || y - z ||_2 < eps } * * @param y y * @param eps * @param size size of z */ struct prox_l2ball_data { INTERFACE(operator_data_t); float* y; float eps; long size; #ifdef USE_CUDA const float* gpu_y; #endif }; static DEF_TYPEID(prox_l2ball_data); #ifdef USE_CUDA static const float* get_y(const struct prox_l2ball_data* data, bool gpu) { const float* y = data->y; if (gpu) { if (NULL == data->gpu_y) ((struct prox_l2ball_data*)data)->gpu_y = md_gpu_move(1, MD_DIMS(data->size), data->y, FL_SIZE); y = data->gpu_y; } return y; } #endif /** * Proximal function for f(z) = Ind{ || y - z ||_2 < eps } * Solution is y + (x - y) * q, where q = eps / norm(x - y) if norm(x - y) > eps, 1 o.w. * * @param prox_data should be of type prox_l2ball_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_l2ball_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { UNUSED(mu); auto pdata = CAST_DOWN(prox_l2ball_data, prox_data); #ifdef USE_CUDA const float* y = get_y(pdata, cuda_ondevice(x_plus_u)); #else const float* y = pdata->y; #endif if (NULL != y) md_sub(1, MD_DIMS(pdata->size), z, x_plus_u, y); else md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE); float q1 = md_norm(1, MD_DIMS(pdata->size), z); if (q1 > pdata->eps) md_smul(1, MD_DIMS(pdata->size), z, z, pdata->eps / q1); if (NULL != y) md_add(1, MD_DIMS(pdata->size), z, z, y); } static void prox_l2ball_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { prox_l2ball_fun(_data, mu, (float*)dst, (const float*)src); } static void prox_l2ball_del(const operator_data_t* _data) { auto data = CAST_DOWN(prox_l2ball_data, _data); #ifdef USE_CUDA if (NULL != data->gpu_y) md_free(data->gpu_y); #endif xfree(data); } const struct operator_p_s* prox_l2ball_create(unsigned int N, const long dims[N], float eps, const complex float* y) { PTR_ALLOC(struct prox_l2ball_data, pdata); SET_TYPEID(prox_l2ball_data, pdata); pdata->y = (float*)y; pdata->eps = eps; pdata->size = md_calc_size(N, dims) * 2; #ifdef USE_CUDA pdata->gpu_y = NULL; #endif return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_l2ball_apply, prox_l2ball_del); } #if 0 /** * Data for computing prox_thresh_fun: * Proximal function for f(z) = lambda || z ||_1 * * @param thresh function to apply SoftThresh * @param data data used by thresh function * @param lambda regularization */ struct prox_thresh_data { void (*thresh)(void* _data, float lambda, float* _dst, const float* _src); void* data; float lambda; }; /** * Proximal function for f(z) = lambda || z ||_1 * Solution is z = SoftThresh(x_plus_u, lambda * mu) * * @param prox_data should be of type prox_thresh_data */ void prox_thresh_fun(void* prox_data, float mu, float* z, const float* x_plus_u) { struct prox_thresh_data* pdata = (struct prox_thresh_data*)prox_data; pdata->thresh(pdata->data, pdata->lambda * mu, z, x_plus_u); } static void prox_thresh_apply(const void* _data, float mu, complex float* dst, const complex float* src) { prox_thresh_fun((void*)_data, mu, (float*)dst, (const float*)src); } static void prox_thresh_del(const void* _data) { xfree((void*)_data); } const struct operator_p_s* prox_thresh_create(unsigned int N, const long dims[N], float lambda, void (*thresh)(void* _data, float lambda, float* _dst, const float* _src), void* data) { PTR_ALLOC(struct prox_thresh_data, pdata); pdata->thresh = thresh; pdata->lambda = lambda; pdata->data = data; return operator_p_create(N, dims, dims, PTR_PASS(pdata), prox_thresh_apply, prox_thresh_del); } #endif /** * Data for computing prox_zero_fun: * Proximal function for f(z) = 0 * * @param size size of z */ struct prox_zero_data { INTERFACE(operator_data_t); long size; }; static DEF_TYPEID(prox_zero_data); /** * Proximal function for f(z) = 0 * Solution is z = x_plus_u * * @param prox_data should be of type prox_zero_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_zero_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { UNUSED(mu); auto pdata = CAST_DOWN(prox_zero_data, prox_data); md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE); } static void prox_zero_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { prox_zero_fun(_data, mu, (float*)dst, (const float*)src); } static void prox_zero_del(const operator_data_t* _data) { xfree(CAST_DOWN(prox_zero_data, _data)); } const struct operator_p_s* prox_zero_create(unsigned int N, const long dims[N]) { PTR_ALLOC(struct prox_zero_data, pdata); SET_TYPEID(prox_zero_data, pdata); pdata->size = md_calc_size(N, dims) * 2; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_zero_apply, prox_zero_del); } /** * Data for computing prox_lineq_fun: * Proximal function for f(z) = 1{ A z = y } * Assumes AA^T = I * Solution is z = x - A^T A x + A^T y * * @param op linop A * @param adj A^H y * @param tmp tmp */ struct prox_lineq_data { INTERFACE(operator_data_t); const struct linop_s* op; complex float* adj; complex float* tmp; }; static DEF_TYPEID(prox_lineq_data); static void prox_lineq_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { UNUSED(mu); auto pdata = CAST_DOWN(prox_lineq_data, _data); const struct linop_s* op = pdata->op; linop_normal(op, linop_domain(op)->N, linop_domain(op)->dims, pdata->tmp, src); md_zsub(linop_domain(op)->N, linop_domain(op)->dims, dst, src, pdata->tmp); md_zadd(linop_domain(op)->N, linop_domain(op)->dims, dst, dst, pdata->adj); } static void prox_lineq_del(const operator_data_t* _data) { auto pdata = CAST_DOWN(prox_lineq_data, _data); md_free(pdata->adj); md_free(pdata->tmp); xfree(pdata); } const struct operator_p_s* prox_lineq_create(const struct linop_s* op, const complex float* y) { PTR_ALLOC(struct prox_lineq_data, pdata); SET_TYPEID(prox_lineq_data, pdata); unsigned int N = linop_domain(op)->N; const long* dims = linop_domain(op)->dims; pdata->op = op; pdata->adj = md_alloc_sameplace(N, dims, CFL_SIZE, y); linop_adjoint(op, N, dims, pdata->adj, N, linop_codomain(op)->dims, y); pdata->tmp = md_alloc_sameplace(N, dims, CFL_SIZE, y); return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_lineq_apply, prox_lineq_del); } /** * Data for computing prox_ineq_fun: * Proximal function for f(z) = 1{ z <= b } * and f(z) = 1{ z >= b } * * @param b b * @param size size of z */ struct prox_ineq_data { INTERFACE(operator_data_t); const float* b; long size; bool positive; }; static DEF_TYPEID(prox_ineq_data); static void prox_ineq_fun(const operator_data_t* _data, float mu, float* dst, const float* src) { UNUSED(mu); auto pdata = CAST_DOWN(prox_ineq_data, _data); if (NULL == pdata->b) (pdata->positive ? md_smax : md_smin)(1, MD_DIMS(pdata->size), dst, src, 0.); else (pdata->positive ? md_max : md_min)(1, MD_DIMS(pdata->size), dst, src, pdata->b); } static void prox_ineq_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { prox_ineq_fun(_data, mu, (float*)dst, (const float*)src); } static void prox_ineq_del(const operator_data_t* _data) { xfree(CAST_DOWN(prox_ineq_data, _data)); } static const struct operator_p_s* prox_ineq_create(unsigned int N, const long dims[N], const complex float* b, bool positive) { PTR_ALLOC(struct prox_ineq_data, pdata); SET_TYPEID(prox_ineq_data, pdata); pdata->size = md_calc_size(N, dims) * 2; pdata->b = (const float*)b; pdata->positive = positive; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_ineq_apply, prox_ineq_del); } /* * Proximal function for less than or equal to: * f(z) = 1{z <= b} */ const struct operator_p_s* prox_lesseq_create(unsigned int N, const long dims[N], const complex float* b) { return prox_ineq_create(N, dims, b, false); } /* * Proximal function for greater than or equal to: * f(z) = 1{z >= b} */ const struct operator_p_s* prox_greq_create(unsigned int N, const long dims[N], const complex float* b) { return prox_ineq_create(N, dims, b, true); } /* * Proximal function for nonnegative orthant * f(z) = 1{z >= 0} */ const struct operator_p_s* prox_nonneg_create(unsigned int N, const long dims[N]) { return prox_ineq_create(N, dims, NULL, true); } struct prox_rvc_data { INTERFACE(operator_data_t); long size; }; static DEF_TYPEID(prox_rvc_data); static void prox_rvc_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { UNUSED(mu); auto pdata = CAST_DOWN(prox_rvc_data, _data); md_zreal(1, MD_DIMS(pdata->size), dst, src); } static void prox_rvc_del(const operator_data_t* _data) { xfree(CAST_DOWN(prox_rvc_data, _data)); } /* * Proximal function for real-value constraint */ const struct operator_p_s* prox_rvc_create(unsigned int N, const long dims[N]) { PTR_ALLOC(struct prox_rvc_data, pdata); SET_TYPEID(prox_rvc_data, pdata); pdata->size = md_calc_size(N, dims); return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(pdata)), prox_rvc_apply, prox_rvc_del); } struct auto_norm_s { INTERFACE(operator_data_t); long flags; const struct operator_p_s* op; }; DEF_TYPEID(auto_norm_s); static void auto_norm_apply(const operator_data_t* _data, float mu, complex float* y, const complex float* x) { auto data = CAST_DOWN(auto_norm_s, _data); auto io = operator_p_domain(data->op); unsigned int N = io->N; long sdims[N]; md_select_dims(N, ~data->flags, sdims, io->dims); long sstrs[N]; md_calc_strides(N, sstrs, sdims, CFL_SIZE); #if 0 complex float* scale = md_alloc_sameplace(N, sdims, CFL_SIZE, x); md_zrss(N, io->dims, data->flags, scale, x); md_zdiv2(N, io->dims, io->strs, y, io->strs, x, sstrs, scale); #else long pos[N]; for (unsigned int i = 0; i < N; i++) pos[i] = 0; long xdims[N]; md_select_dims(N, data->flags, xdims, io->dims); complex float* scale = md_alloc(N, sdims, CFL_SIZE); do { MD_ACCESS(N, sstrs, pos, scale) = md_znorm2(N, xdims, io->strs, &MD_ACCESS(N, io->strs, pos, x)); complex float val = MD_ACCESS(N, sstrs, pos, scale); md_zsmul2(N, xdims, io->strs, &MD_ACCESS(N, io->strs, pos, y), io->strs, &MD_ACCESS(N, io->strs, pos, x), (0. == val) ? 0. : (1. / val)); } while (md_next(N, io->dims, ~data->flags, pos)); #endif operator_p_apply_unchecked(data->op, mu, y, y); // FIXME: input == output #if 0 md_zmul2(N, io->dims, io->strs, y, io->strs, y, sstrs, scale); #else for (unsigned int i = 0; i < N; i++) pos[i] = 0; do { complex float val = MD_ACCESS(N, sstrs, pos, scale); md_zsmul2(N, xdims, io->strs, &MD_ACCESS(N, io->strs, pos, y), io->strs, &MD_ACCESS(N, io->strs, pos, y), val); } while (md_next(N, io->dims, ~data->flags, pos)); #endif md_free(scale); } static void auto_norm_del(const operator_data_t* _data) { auto data = CAST_DOWN(auto_norm_s, _data); operator_p_free(data->op); xfree(data); } /* This functor normalizes data along given dimensions and undoes * the normalization after application of the operator. * */ const struct operator_p_s* op_p_auto_normalize(const struct operator_p_s* op, long flags) { PTR_ALLOC(struct auto_norm_s, data); SET_TYPEID(auto_norm_s, data); data->flags = flags; data->op = operator_p_ref(op); auto io_in = operator_p_domain(op); auto io_out = operator_p_codomain(op); unsigned int N = io_in->N; long dims[N]; md_copy_dims(N, dims, io_in->dims); long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); assert(N == io_out->N); assert(md_check_compat(N, 0L, dims, io_out->dims)); assert(md_check_compat(N, 0L, strs, io_in->strs)); assert(md_check_compat(N, 0L, strs, io_out->strs)); return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), auto_norm_apply, auto_norm_del); } bart-0.5.00/src/iter/prox.h000066400000000000000000000030601353046746100154270ustar00rootroot00000000000000/* Copyright 2014-2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __PROX_H #define __PROX_H #include "misc/cppwrap.h" struct operator_p_s; struct linop_s; extern const struct operator_p_s* prox_normaleq_create(const struct linop_s* op, const _Complex float* y); extern const struct operator_p_s* prox_leastsquares_create(unsigned int N, const long dims[__VLA(N)], float lambda, const _Complex float* y); extern const struct operator_p_s* prox_l2norm_create(unsigned int N, const long dims[__VLA(N)], float lambda); extern const struct operator_p_s* prox_l2ball_create(unsigned int N, const long dims[__VLA(N)], float eps, const _Complex float* center); extern const struct operator_p_s* prox_zero_create(unsigned int N, const long dims[__VLA(N)]); extern const struct operator_p_s* prox_lineq_create(const struct linop_s* op, const _Complex float* y); extern const struct operator_p_s* prox_lesseq_create(unsigned int N, const long dims[__VLA(N)], const _Complex float* b); extern const struct operator_p_s* prox_greq_create(unsigned int N, const long dims[__VLA(N)], const _Complex float* b); extern const struct operator_p_s* prox_rvc_create(unsigned int N, const long dims[__VLA(N)]); extern const struct operator_p_s* prox_nonneg_create(unsigned int N, const long dims[__VLA(N)]); struct operator_p_s; extern const struct operator_p_s* op_p_auto_normalize(const struct operator_p_s*, long flags); #include "misc/cppwrap.h" #endif bart-0.5.00/src/iter/thresh.c000066400000000000000000000164531353046746100157410ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2014 Jonathan Tamir * 2013-2018 Martin Uecker * 2017 Sofia Dimoudi */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops_p.h" #include "num/ops.h" #include "num/iovec.h" #include "linops/linop.h" #include "misc/misc.h" #include "misc/debug.h" #include "thresh.h" /** * Contains parameters for soft threshold functions * * @param lambda threshold parameter * @param D number of dimensions * @param dim dimensions of input * @param str strides of input * @param flags bitmask for joint thresholding * @param unitary_op linear operator if using unitary soft thresholding */ struct thresh_s { INTERFACE(operator_data_t); float lambda; //for soft thresholding unsigned int k; // for hard thresholding int D; const long* dim; const long* str; const long* norm_dim; unsigned int flags; const struct linop_s* unitary_op; }; static DEF_TYPEID(thresh_s); static void softthresh_apply(const operator_data_t* _data, float mu, complex float* optr, const complex float* iptr) { const auto data = CAST_DOWN(thresh_s, _data); if (0. == mu) { md_copy(data->D, data->dim, optr, iptr, CFL_SIZE); } else { complex float* tmp_norm = md_alloc_sameplace(data->D, data->norm_dim, CFL_SIZE, optr); md_zsoftthresh_core2(data->D, data->dim, data->lambda * mu, data->flags, tmp_norm, data->str, optr, data->str, iptr); md_free(tmp_norm); } } static void unisoftthresh_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(thresh_s, _data); if (0. == mu) { md_copy(data->D, data->dim, dst, src, CFL_SIZE); } else { const long* transform_dims = linop_codomain(data->unitary_op)->dims; const long* transform_strs = linop_codomain(data->unitary_op)->strs; complex float* tmp = md_alloc_sameplace(data->D, transform_dims, CFL_SIZE, dst); linop_forward(data->unitary_op, data->D, transform_dims, tmp, data->D, data->dim, src); complex float* tmp_norm = md_alloc_sameplace(data->D, data->norm_dim, CFL_SIZE, dst); md_zsoftthresh_core2(data->D, transform_dims, data->lambda * mu, data->flags, tmp_norm, transform_strs, tmp, transform_strs, tmp); md_free(tmp_norm); linop_adjoint(data->unitary_op, data->D, data->dim, dst, data->D, transform_dims, tmp); md_free(tmp); } } static void hardthresh_apply(const operator_data_t* _data, float mu, complex float* optr, const complex float* iptr) { UNUSED(mu); const auto data = CAST_DOWN(thresh_s, _data); complex float* tmp_norm = md_alloc_sameplace(data->D, data->norm_dim, CFL_SIZE, optr); //only producing the support mask md_zhardthresh_mask2(data->D, data->dim, data->k, data->flags, tmp_norm, data->str, optr, data->str, iptr); md_free(tmp_norm); } static void thresh_del(const operator_data_t* _data) { const auto data = CAST_DOWN(thresh_s, _data); xfree(data->dim); xfree(data->str); xfree(data->norm_dim); xfree(data); } /** * Proximal operator for l1-norm: f(x) = lambda || x ||_1 * y = ST(x, lambda) * 1) computes resid = MAX( (norm(x) - lambda)/norm(x), 0 ) * 2) multiplies y = resid * x * * @param D number of dimensions * @param dim dimensions of x * @param lambda threshold parameter * @param flags bitmask for joint soft-thresholding */ const struct operator_p_s* prox_thresh_create(unsigned int D, const long dim[D], const float lambda, const unsigned long flags) { PTR_ALLOC(struct thresh_s, data); SET_TYPEID(thresh_s, data); data->lambda = lambda; data->D = D; data->flags = flags; data->unitary_op = NULL; PTR_ALLOC(long[D], ndim); md_copy_dims(D, *ndim, dim); data->dim = *PTR_PASS(ndim); // norm dimensions are the flagged input dimensions PTR_ALLOC(long[D], norm_dim); md_select_dims(D, ~flags, *norm_dim, data->dim); data->norm_dim = *PTR_PASS(norm_dim); PTR_ALLOC(long[D], nstr); md_calc_strides(D, *nstr, data->dim, CFL_SIZE); data->str = *PTR_PASS(nstr); return operator_p_create(D, dim, D, dim, CAST_UP(PTR_PASS(data)), softthresh_apply, thresh_del); } /** * Proximal operator for l1-norm with unitary transform: f(x) = lambda || T x ||_1 * * @param D number of dimensions * @param dim dimensions of x * @param lambda threshold parameter * @param unitary_op unitary linear operator * @param flags bitmask for joint soft-thresholding */ extern const struct operator_p_s* prox_unithresh_create(unsigned int D, const struct linop_s* unitary_op, const float lambda, const unsigned long flags) { PTR_ALLOC(struct thresh_s, data); SET_TYPEID(thresh_s, data); data->lambda = lambda; data->D = D; data->flags = flags; data->unitary_op = unitary_op; const long* dims = linop_domain(unitary_op)->dims; PTR_ALLOC(long[D], ndim); md_copy_dims(D, *ndim, dims); data->dim = *PTR_PASS(ndim); PTR_ALLOC(long[D], nstr); md_calc_strides(D, *nstr, data->dim, CFL_SIZE); data->str = *PTR_PASS(nstr); // norm dimensions are the flagged transform dimensions // FIXME should use linop_codomain(unitary_op)->N PTR_ALLOC(long[D], norm_dim); md_select_dims(D, ~flags, *norm_dim, linop_codomain(unitary_op)->dims); data->norm_dim = *PTR_PASS(norm_dim); return operator_p_create(D, dims, D, dims, CAST_UP(PTR_PASS(data)), unisoftthresh_apply, thresh_del); } /** * Thresholding operator for l0-norm: f(x) = || x ||_0 <= k, as used in NIHT algorithm. * y = HT(x, k) (hard thresholding, ie keeping the k largest elements). * * @param D number of dimensions * @param dim dimensions of x * @param k threshold parameter (non-zero elements to keep) * @param flags bitmask for joint thresholding */ const struct operator_p_s* prox_niht_thresh_create(unsigned int D, const long dim[D], const unsigned int k, const unsigned long flags) { PTR_ALLOC(struct thresh_s, data); SET_TYPEID(thresh_s, data); data->lambda = 0.; data->k = k; data->D = D; data->flags = flags; data->unitary_op = NULL; PTR_ALLOC(long[D], ndim); md_copy_dims(D, *ndim, dim); data->dim = *PTR_PASS(ndim); // norm dimensions are the flagged input dimensions PTR_ALLOC(long[D], norm_dim); md_select_dims(D, ~flags, *norm_dim, data->dim); data->norm_dim = *PTR_PASS(norm_dim); PTR_ALLOC(long[D], nstr); md_calc_strides(D, *nstr, data->dim, CFL_SIZE); data->str = *PTR_PASS(nstr); return operator_p_create(D, dim, D, dim, CAST_UP(PTR_PASS(data)), hardthresh_apply, thresh_del); } void thresh_free(const struct operator_p_s* o) { operator_p_free(o); } /** * Change the threshold parameter of the soft threshold function * * @param o soft threshold prox operator * @param lambda new threshold parameter */ void set_thresh_lambda(const struct operator_p_s* o, const float lambda) { auto data = CAST_DOWN(thresh_s, operator_p_get_data(o)); data->lambda = lambda; } /** * Returns the regularization parameter of the soft threshold function * * @param o soft threshold prox operator */ float get_thresh_lambda(const struct operator_p_s* o) { auto data = CAST_DOWN(thresh_s, operator_p_get_data(o)); return data->lambda; } bart-0.5.00/src/iter/thresh.h000066400000000000000000000020061353046746100157330ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __THRESH #define __THRESH #include "misc/cppwrap.h" struct operator_p_s; extern const struct operator_p_s* prox_thresh_create(unsigned int D, const long dim[__VLA(D)], const float lambda, const unsigned long flags); extern const struct operator_p_s* prox_niht_thresh_create(unsigned int D, const long dim[D], const unsigned int k, const unsigned long flags); extern void thresh_free(const struct operator_p_s* data); extern void set_thresh_lambda(const struct operator_p_s* o, const float lambda); extern float get_thresh_lambda(const struct operator_p_s* o); struct linop_s; extern const struct operator_p_s* prox_unithresh_create(unsigned int D, const struct linop_s* unitary_op, const float lambda, const unsigned long flags); #include "misc/cppwrap.h" #endif bart-0.5.00/src/iter/vec.c000066400000000000000000000004741353046746100152150ustar00rootroot00000000000000 #include "num/vecops.h" #include "num/gpuops.h" #include "misc/misc.h" #include "vec.h" // defined in vecops.c and gpuops.c const struct vec_iter_s* select_vecops(const float* x) { #ifdef USE_CUDA return cuda_ondevice(x) ? &gpu_iter_ops : &cpu_iter_ops; #else UNUSED(x); return &cpu_iter_ops; #endif } bart-0.5.00/src/iter/vec.h000066400000000000000000000021661353046746100152220ustar00rootroot00000000000000 #ifndef __ITER_VEC_H #define __ITER_VEC_H struct vec_iter_s { float* (*allocate)(long N); void (*del)(float* x); void (*clear)(long N, float* x); void (*copy)(long N, float* a, const float* x); void (*swap)(long N, float* a, float* x); double (*norm)(long N, const float* x); double (*dot)(long N, const float* x, const float* y); void (*sub)(long N, float* a, const float* x, const float* y); void (*add)(long N, float* a, const float* x, const float* y); void (*smul)(long N, float alpha, float* a, const float* x); void (*xpay)(long N, float alpha, float* a, const float* x); void (*axpy)(long N, float* a, float alpha, const float* x); void (*axpbz)(long N, float* out, const float a, const float* x, const float b, const float* z); void (*zmul)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zsmax)(long N, _Complex float val, _Complex float* dst, const _Complex float* src1); }; #ifdef USE_CUDA extern const struct vec_iter_s gpu_iter_ops; #endif extern const struct vec_iter_s cpu_iter_ops; extern const struct vec_iter_s* select_vecops(const float* x); #endif bart-0.5.00/src/itsense.c000066400000000000000000000120031353046746100151360ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * * * Basic iterative sense reconstruction */ #include #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "num/ops.h" #include "iter/iter.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/mmio.h" #include "misc/mri.h" #include "misc/types.h" struct sense_data { INTERFACE(operator_data_t); long sens_dims[DIMS]; long sens_strs[DIMS]; long imgs_dims[DIMS]; long imgs_strs[DIMS]; long data_dims[DIMS]; long data_strs[DIMS]; long mask_dims[DIMS]; long mask_strs[DIMS]; const complex float* sens; const complex float* pattern; complex float* tmp; float alpha; }; static DEF_TYPEID(sense_data); static void sense_forward(const struct sense_data* data, complex float* out, const complex float* imgs) { md_clear(DIMS, data->data_dims, out, CFL_SIZE); md_zfmac2(DIMS, data->sens_dims, data->data_strs, out, data->sens_strs, data->sens, data->imgs_strs, imgs); fftc(DIMS, data->data_dims, FFT_FLAGS, out, out); fftscale(DIMS, data->data_dims, FFT_FLAGS, out, out); md_zmul2(DIMS, data->data_dims, data->data_strs, out, data->data_strs, out, data->mask_strs, data->pattern); } static void sense_adjoint(const struct sense_data* data, complex float* imgs, const complex float* out) { md_zmulc2(DIMS, data->data_dims, data->data_strs, data->tmp, data->data_strs, out, data->mask_strs, data->pattern); ifftc(DIMS, data->data_dims, FFT_FLAGS, data->tmp, data->tmp); fftscale(DIMS, data->data_dims, FFT_FLAGS, data->tmp, data->tmp); md_clear(DIMS, data->imgs_dims, imgs, CFL_SIZE); md_zfmacc2(DIMS, data->sens_dims, data->imgs_strs, imgs, data->data_strs, data->tmp, data->sens_strs, data->sens); } static void sense_normal(const operator_data_t* _data, unsigned int N, void* args[N]) { const struct sense_data* data = CAST_DOWN(sense_data, _data); assert(2 == N); float* out = args[0]; const float* in = args[1]; sense_forward(data, data->tmp, (const complex float*)in); sense_adjoint(data, (complex float*)out, data->tmp); } static void sense_reco(struct sense_data* data, complex float* imgs, const complex float* kspace) { complex float* adj = md_alloc(DIMS, data->imgs_dims, CFL_SIZE); md_clear(DIMS, data->imgs_dims, imgs, CFL_SIZE); sense_adjoint(data, adj, kspace); long size = 2 * md_calc_size(DIMS, data->imgs_dims); // multiply by 2 for float size const struct operator_s* op = operator_create(DIMS, data->imgs_dims, DIMS, data->imgs_dims, CAST_UP(data), sense_normal, NULL); struct iter_conjgrad_conf conf = iter_conjgrad_defaults; conf.maxiter = 100; conf.l2lambda = data->alpha; conf.tol = 1.E-3; iter_conjgrad(CAST_UP(&conf), op, NULL, size, (float*)imgs, (const float*)adj, NULL); operator_free(op); md_free(adj); } static bool check_dimensions(struct sense_data* data) { bool ok = true; for (int i = 0; i < 3; i++) { ok &= (data->mask_dims[i] == data->sens_dims[i]); ok &= (data->data_dims[i] == data->sens_dims[i]); ok &= (data->imgs_dims[i] == data->sens_dims[i]); } ok &= (data->data_dims[COIL_DIM] == data->sens_dims[COIL_DIM]); ok &= (data->imgs_dims[MAPS_DIM] == data->sens_dims[MAPS_DIM]); ok &= (1 == data->data_dims[MAPS_DIM]); ok &= (1 == data->mask_dims[COIL_DIM]); ok &= (1 == data->mask_dims[MAPS_DIM]); ok &= (1 == data->imgs_dims[COIL_DIM]); return ok; } static const char usage_str[] = "alpha "; static const char help_str[] = "A simplified implementation of iterative sense reconstruction\n" "with l2-regularization.\n"; int main_itsense(int argc, char* argv[]) { mini_cmdline(&argc, argv, 5, usage_str, help_str); struct sense_data data; SET_TYPEID(sense_data, &data); data.alpha = atof(argv[1]); complex float* kspace = load_cfl(argv[3], DIMS, data.data_dims); data.sens = load_cfl(argv[2], DIMS, data.sens_dims); data.pattern = load_cfl(argv[4], DIMS, data.mask_dims); // 1 2 4 8 md_select_dims(DIMS, ~COIL_FLAG, data.imgs_dims, data.sens_dims); assert(check_dimensions(&data)); complex float* image = create_cfl(argv[5], DIMS, data.imgs_dims); md_calc_strides(DIMS, data.sens_strs, data.sens_dims, CFL_SIZE); md_calc_strides(DIMS, data.imgs_strs, data.imgs_dims, CFL_SIZE); md_calc_strides(DIMS, data.data_strs, data.data_dims, CFL_SIZE); md_calc_strides(DIMS, data.mask_strs, data.mask_dims, CFL_SIZE); data.tmp = md_alloc(DIMS, data.data_dims, CFL_SIZE); num_init(); sense_reco(&data, image, kspace); unmap_cfl(DIMS, data.imgs_dims, image); unmap_cfl(DIMS, data.mask_dims, data.pattern); unmap_cfl(DIMS, data.sens_dims, data.sens); unmap_cfl(DIMS, data.data_dims, data.sens); md_free(data.tmp); return 0; } bart-0.5.00/src/join.c000066400000000000000000000060031353046746100144260ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013, 2015 Martin Uecker * 2015 Jonathan Tamir */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "dimension ... "; static const char help_str[] = "Join input files along {dimensions}. All other dimensions must have the same size.\n" "\t Example 1: join 0 slice_001 slice_002 slice_003 full_data\n" "\t Example 2: join 0 `seq -f \"slice_%%03g\" 0 255` full_data\n"; int main_join(int argc, char* argv[]) { bool append = false; const struct opt_s opts[] = { OPT_SET('a', &append, "append - only works for cfl files!"), }; cmdline(&argc, argv, 3, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); int N = DIMS; int dim = atoi(argv[1]); assert(dim < N); int count = argc - 3; if (append) { count += 1; assert(count > 1); int len = strlen(argv[argc - 1]); char buf[len + 5]; strcpy(buf, argv[argc - 1]); strcat(buf, ".cfl"); if (-1 == access(buf, F_OK)) { // make sure we do not have any other file format strcpy(buf, argv[argc - 1]); strcat(buf, ".coo"); assert(-1 == access(buf, F_OK)); strcpy(buf, argv[argc - 1]); strcat(buf, ".ra"); assert(-1 == access(buf, F_OK)); count--; append = false; } } long in_dims[count][N]; long offsets[count]; complex float* idata[count]; long sum = 0; // figure out size of output for (int l = 0, i = 0; i < count; i++) { const char* name = NULL; if (append && (i == 0)) { name = argv[argc - 1]; } else { name = argv[2 + l++]; } debug_printf(DP_DEBUG1, "loading %s\n", name); idata[i] = load_cfl(name, N, in_dims[i]); offsets[i] = sum; sum += in_dims[i][dim]; for (int j = 0; j < N; j++) assert((dim == j) || (in_dims[0][j] == in_dims[i][j])); } long out_dims[N]; for (int i = 0; i < N; i++) out_dims[i] = in_dims[0][i]; out_dims[dim] = sum; complex float* out_data = create_cfl(argv[argc - 1], N, out_dims); long ostr[N]; md_calc_strides(N, ostr, out_dims, CFL_SIZE); #pragma omp parallel for for (int i = 0; i < count; i++) { if (!(append && (0 == i))) { long pos[N]; md_singleton_strides(N, pos); pos[dim] = offsets[i]; long istr[N]; md_calc_strides(N, istr, in_dims[i], CFL_SIZE); md_copy_block(N, pos, out_dims, out_data, in_dims[i], idata[i], CFL_SIZE); } unmap_cfl(N, in_dims[i], idata[i]); debug_printf(DP_DEBUG1, "done copying file %d\n", i); } unmap_cfl(N, out_dims, out_data); return 0; } bart-0.5.00/src/lapacke/000077500000000000000000000000001353046746100147245ustar00rootroot00000000000000bart-0.5.00/src/lapacke/LICENSE000066400000000000000000000030431353046746100157310ustar00rootroot00000000000000 Copyright (c) 2012, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bart-0.5.00/src/lapacke/README000066400000000000000000000004151353046746100156040ustar00rootroot00000000000000 This is a small subset of LAPACKE needed for BART extracted from the Debian package of lapack with version 3.5.0-4. It is provided here as a workaround for systems without LAPACKE. Add the flag NOLAPACKE=1 to Makefile.local if LAPACKE is not available on the system. bart-0.5.00/src/lapacke/lapacke.h000066400000000000000000040464111353046746100165070ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2010, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** * Contents: Native C interface to LAPACK * Author: Intel Corporation * Generated November, 2011 *****************************************************************************/ #ifndef _LAPACKE_H_ #define _LAPACKE_H_ /* * Turn on HAVE_LAPACK_CONFIG_H to redefine C-LAPACK datatypes */ #ifdef HAVE_LAPACK_CONFIG_H #include "lapacke_config.h" #endif #include #ifndef lapack_int #define lapack_int int #endif #ifndef lapack_logical #define lapack_logical lapack_int #endif /* Complex types are structures equivalent to the * Fortran complex types COMPLEX(4) and COMPLEX(8). * * One can also redefine the types with his own types * for example by including in the code definitions like * * #define lapack_complex_float std::complex * #define lapack_complex_double std::complex * * or define these types in the command line: * * -Dlapack_complex_float="std::complex" * -Dlapack_complex_double="std::complex" */ #ifndef LAPACK_COMPLEX_CUSTOM /* Complex type (single precision) */ #ifndef lapack_complex_float #include #define lapack_complex_float float _Complex #endif #ifndef lapack_complex_float_real #define lapack_complex_float_real(z) (creal(z)) #endif #ifndef lapack_complex_float_imag #define lapack_complex_float_imag(z) (cimag(z)) #endif lapack_complex_float lapack_make_complex_float( float re, float im ); /* Complex type (double precision) */ #ifndef lapack_complex_double #include #define lapack_complex_double double _Complex #endif #ifndef lapack_complex_double_real #define lapack_complex_double_real(z) (creal(z)) #endif #ifndef lapack_complex_double_imag #define lapack_complex_double_imag(z) (cimag(z)) #endif lapack_complex_double lapack_make_complex_double( double re, double im ); #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef LAPACKE_malloc #define LAPACKE_malloc( size ) malloc( size ) #endif #ifndef LAPACKE_free #define LAPACKE_free( p ) free( p ) #endif #define LAPACK_C2INT( x ) (lapack_int)(*((float*)&x )) #define LAPACK_Z2INT( x ) (lapack_int)(*((double*)&x )) #define LAPACK_ROW_MAJOR 101 #define LAPACK_COL_MAJOR 102 #define LAPACK_WORK_MEMORY_ERROR -1010 #define LAPACK_TRANSPOSE_MEMORY_ERROR -1011 /* Callback logical functions of one, two, or three arguments are used * to select eigenvalues to sort to the top left of the Schur form. * The value is selected if function returns TRUE (non-zero). */ typedef lapack_logical (*LAPACK_S_SELECT2) ( const float*, const float* ); typedef lapack_logical (*LAPACK_S_SELECT3) ( const float*, const float*, const float* ); typedef lapack_logical (*LAPACK_D_SELECT2) ( const double*, const double* ); typedef lapack_logical (*LAPACK_D_SELECT3) ( const double*, const double*, const double* ); typedef lapack_logical (*LAPACK_C_SELECT1) ( const lapack_complex_float* ); typedef lapack_logical (*LAPACK_C_SELECT2) ( const lapack_complex_float*, const lapack_complex_float* ); typedef lapack_logical (*LAPACK_Z_SELECT1) ( const lapack_complex_double* ); typedef lapack_logical (*LAPACK_Z_SELECT2) ( const lapack_complex_double*, const lapack_complex_double* ); #include "lapacke_mangling.h" #define LAPACK_lsame LAPACK_GLOBAL(lsame,LSAME) lapack_logical LAPACK_lsame( char* ca, char* cb, lapack_int lca, lapack_int lcb ); /* C-LAPACK function prototypes */ lapack_int LAPACKE_sbdsdc( int matrix_order, char uplo, char compq, lapack_int n, float* d, float* e, float* u, lapack_int ldu, float* vt, lapack_int ldvt, float* q, lapack_int* iq ); lapack_int LAPACKE_dbdsdc( int matrix_order, char uplo, char compq, lapack_int n, double* d, double* e, double* u, lapack_int ldu, double* vt, lapack_int ldvt, double* q, lapack_int* iq ); lapack_int LAPACKE_sbdsqr( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, float* d, float* e, float* vt, lapack_int ldvt, float* u, lapack_int ldu, float* c, lapack_int ldc ); lapack_int LAPACKE_dbdsqr( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, double* d, double* e, double* vt, lapack_int ldvt, double* u, lapack_int ldu, double* c, lapack_int ldc ); lapack_int LAPACKE_cbdsqr( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, float* d, float* e, lapack_complex_float* vt, lapack_int ldvt, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zbdsqr( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, double* d, double* e, lapack_complex_double* vt, lapack_int ldvt, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_sdisna( char job, lapack_int m, lapack_int n, const float* d, float* sep ); lapack_int LAPACKE_ddisna( char job, lapack_int m, lapack_int n, const double* d, double* sep ); lapack_int LAPACKE_sgbbrd( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, float* ab, lapack_int ldab, float* d, float* e, float* q, lapack_int ldq, float* pt, lapack_int ldpt, float* c, lapack_int ldc ); lapack_int LAPACKE_dgbbrd( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, double* ab, lapack_int ldab, double* d, double* e, double* q, lapack_int ldq, double* pt, lapack_int ldpt, double* c, lapack_int ldc ); lapack_int LAPACKE_cgbbrd( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, lapack_complex_float* ab, lapack_int ldab, float* d, float* e, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* pt, lapack_int ldpt, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zgbbrd( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, lapack_complex_double* ab, lapack_int ldab, double* d, double* e, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* pt, lapack_int ldpt, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_sgbcon( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const float* ab, lapack_int ldab, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_dgbcon( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const double* ab, lapack_int ldab, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_cgbcon( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float* ab, lapack_int ldab, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_zgbcon( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double* ab, lapack_int ldab, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_sgbequ( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgbequ( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgbequ( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgbequ( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgbequb( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgbequb( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgbequb( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgbequb( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgbrfs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const float* ab, lapack_int ldab, const float* afb, lapack_int ldafb, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dgbrfs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const double* ab, lapack_int ldab, const double* afb, lapack_int ldafb, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cgbrfs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* afb, lapack_int ldafb, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zgbrfs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* afb, lapack_int ldafb, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sgbrfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const float* ab, lapack_int ldab, const float* afb, lapack_int ldafb, const lapack_int* ipiv, const float* r, const float* c, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dgbrfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const double* ab, lapack_int ldab, const double* afb, lapack_int ldafb, const lapack_int* ipiv, const double* r, const double* c, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_cgbrfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* afb, lapack_int ldafb, const lapack_int* ipiv, const float* r, const float* c, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zgbrfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* afb, lapack_int ldafb, const lapack_int* ipiv, const double* r, const double* c, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_sgbsv( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, float* ab, lapack_int ldab, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgbsv( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, double* ab, lapack_int ldab, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgbsv( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgbsv( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgbsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, float* ab, lapack_int ldab, float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* rpivot ); lapack_int LAPACKE_dgbsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, double* ab, lapack_int ldab, double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* rpivot ); lapack_int LAPACKE_cgbsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* rpivot ); lapack_int LAPACKE_zgbsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* rpivot ); lapack_int LAPACKE_sgbsvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, float* ab, lapack_int ldab, float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dgbsvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, double* ab, lapack_int ldab, double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_cgbsvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zgbsvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_sgbtrf( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, float* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_dgbtrf( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, double* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_cgbtrf( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, lapack_complex_float* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_zgbtrf( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, lapack_complex_double* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_sgbtrs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const float* ab, lapack_int ldab, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgbtrs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const double* ab, lapack_int ldab, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgbtrs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgbtrs( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgebak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* scale, lapack_int m, float* v, lapack_int ldv ); lapack_int LAPACKE_dgebak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* scale, lapack_int m, double* v, lapack_int ldv ); lapack_int LAPACKE_cgebak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* scale, lapack_int m, lapack_complex_float* v, lapack_int ldv ); lapack_int LAPACKE_zgebak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* scale, lapack_int m, lapack_complex_double* v, lapack_int ldv ); lapack_int LAPACKE_sgebal( int matrix_order, char job, lapack_int n, float* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, float* scale ); lapack_int LAPACKE_dgebal( int matrix_order, char job, lapack_int n, double* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, double* scale ); lapack_int LAPACKE_cgebal( int matrix_order, char job, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, float* scale ); lapack_int LAPACKE_zgebal( int matrix_order, char job, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, double* scale ); lapack_int LAPACKE_sgebrd( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* d, float* e, float* tauq, float* taup ); lapack_int LAPACKE_dgebrd( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* d, double* e, double* tauq, double* taup ); lapack_int LAPACKE_cgebrd( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* d, float* e, lapack_complex_float* tauq, lapack_complex_float* taup ); lapack_int LAPACKE_zgebrd( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* d, double* e, lapack_complex_double* tauq, lapack_complex_double* taup ); lapack_int LAPACKE_sgecon( int matrix_order, char norm, lapack_int n, const float* a, lapack_int lda, float anorm, float* rcond ); lapack_int LAPACKE_dgecon( int matrix_order, char norm, lapack_int n, const double* a, lapack_int lda, double anorm, double* rcond ); lapack_int LAPACKE_cgecon( int matrix_order, char norm, lapack_int n, const lapack_complex_float* a, lapack_int lda, float anorm, float* rcond ); lapack_int LAPACKE_zgecon( int matrix_order, char norm, lapack_int n, const lapack_complex_double* a, lapack_int lda, double anorm, double* rcond ); lapack_int LAPACKE_sgeequ( int matrix_order, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgeequ( int matrix_order, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgeequ( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgeequ( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgeequb( int matrix_order, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgeequb( int matrix_order, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgeequb( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgeequb( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgees( int matrix_order, char jobvs, char sort, LAPACK_S_SELECT2 select, lapack_int n, float* a, lapack_int lda, lapack_int* sdim, float* wr, float* wi, float* vs, lapack_int ldvs ); lapack_int LAPACKE_dgees( int matrix_order, char jobvs, char sort, LAPACK_D_SELECT2 select, lapack_int n, double* a, lapack_int lda, lapack_int* sdim, double* wr, double* wi, double* vs, lapack_int ldvs ); lapack_int LAPACKE_cgees( int matrix_order, char jobvs, char sort, LAPACK_C_SELECT1 select, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* sdim, lapack_complex_float* w, lapack_complex_float* vs, lapack_int ldvs ); lapack_int LAPACKE_zgees( int matrix_order, char jobvs, char sort, LAPACK_Z_SELECT1 select, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* sdim, lapack_complex_double* w, lapack_complex_double* vs, lapack_int ldvs ); lapack_int LAPACKE_sgeesx( int matrix_order, char jobvs, char sort, LAPACK_S_SELECT2 select, char sense, lapack_int n, float* a, lapack_int lda, lapack_int* sdim, float* wr, float* wi, float* vs, lapack_int ldvs, float* rconde, float* rcondv ); lapack_int LAPACKE_dgeesx( int matrix_order, char jobvs, char sort, LAPACK_D_SELECT2 select, char sense, lapack_int n, double* a, lapack_int lda, lapack_int* sdim, double* wr, double* wi, double* vs, lapack_int ldvs, double* rconde, double* rcondv ); lapack_int LAPACKE_cgeesx( int matrix_order, char jobvs, char sort, LAPACK_C_SELECT1 select, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* sdim, lapack_complex_float* w, lapack_complex_float* vs, lapack_int ldvs, float* rconde, float* rcondv ); lapack_int LAPACKE_zgeesx( int matrix_order, char jobvs, char sort, LAPACK_Z_SELECT1 select, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* sdim, lapack_complex_double* w, lapack_complex_double* vs, lapack_int ldvs, double* rconde, double* rcondv ); lapack_int LAPACKE_sgeev( int matrix_order, char jobvl, char jobvr, lapack_int n, float* a, lapack_int lda, float* wr, float* wi, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr ); lapack_int LAPACKE_dgeev( int matrix_order, char jobvl, char jobvr, lapack_int n, double* a, lapack_int lda, double* wr, double* wi, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr ); lapack_int LAPACKE_cgeev( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* w, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr ); lapack_int LAPACKE_zgeev( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* w, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr ); lapack_int LAPACKE_sgeevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, float* a, lapack_int lda, float* wr, float* wi, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv ); lapack_int LAPACKE_dgeevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, double* a, lapack_int lda, double* wr, double* wi, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv ); lapack_int LAPACKE_cgeevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* w, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv ); lapack_int LAPACKE_zgeevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* w, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv ); lapack_int LAPACKE_sgehrd( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgehrd( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgehrd( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgehrd( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgejsv( int matrix_order, char joba, char jobu, char jobv, char jobr, char jobt, char jobp, lapack_int m, lapack_int n, float* a, lapack_int lda, float* sva, float* u, lapack_int ldu, float* v, lapack_int ldv, float* stat, lapack_int* istat ); lapack_int LAPACKE_dgejsv( int matrix_order, char joba, char jobu, char jobv, char jobr, char jobt, char jobp, lapack_int m, lapack_int n, double* a, lapack_int lda, double* sva, double* u, lapack_int ldu, double* v, lapack_int ldv, double* stat, lapack_int* istat ); lapack_int LAPACKE_sgelq2( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgelq2( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgelq2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgelq2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgelqf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgelqf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgelqf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgelqf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgels( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dgels( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_cgels( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgels( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgelsd( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank ); lapack_int LAPACKE_dgelsd( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank ); lapack_int LAPACKE_cgelsd( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank ); lapack_int LAPACKE_zgelsd( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank ); lapack_int LAPACKE_sgelss( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank ); lapack_int LAPACKE_dgelss( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank ); lapack_int LAPACKE_cgelss( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank ); lapack_int LAPACKE_zgelss( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank ); lapack_int LAPACKE_sgelsy( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* jpvt, float rcond, lapack_int* rank ); lapack_int LAPACKE_dgelsy( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* jpvt, double rcond, lapack_int* rank ); lapack_int LAPACKE_cgelsy( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* jpvt, float rcond, lapack_int* rank ); lapack_int LAPACKE_zgelsy( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* jpvt, double rcond, lapack_int* rank ); lapack_int LAPACKE_sgeqlf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgeqlf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgeqlf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgeqlf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgeqp3( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* jpvt, float* tau ); lapack_int LAPACKE_dgeqp3( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* jpvt, double* tau ); lapack_int LAPACKE_cgeqp3( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* jpvt, lapack_complex_float* tau ); lapack_int LAPACKE_zgeqp3( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* jpvt, lapack_complex_double* tau ); lapack_int LAPACKE_sgeqpf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* jpvt, float* tau ); lapack_int LAPACKE_dgeqpf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* jpvt, double* tau ); lapack_int LAPACKE_cgeqpf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* jpvt, lapack_complex_float* tau ); lapack_int LAPACKE_zgeqpf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* jpvt, lapack_complex_double* tau ); lapack_int LAPACKE_sgeqr2( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgeqr2( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgeqr2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgeqr2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgeqrf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgeqrf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgeqrf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgeqrf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgeqrfp( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgeqrfp( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgeqrfp( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgeqrfp( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgerfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dgerfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cgerfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zgerfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sgerfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* r, const float* c, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dgerfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* r, const double* c, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_cgerfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const float* r, const float* c, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zgerfsx( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const double* r, const double* c, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_sgerqf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dgerqf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_cgerqf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_zgerqf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_sgesdd( int matrix_order, char jobz, lapack_int m, lapack_int n, float* a, lapack_int lda, float* s, float* u, lapack_int ldu, float* vt, lapack_int ldvt ); lapack_int LAPACKE_dgesdd( int matrix_order, char jobz, lapack_int m, lapack_int n, double* a, lapack_int lda, double* s, double* u, lapack_int ldu, double* vt, lapack_int ldvt ); lapack_int LAPACKE_cgesdd( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* vt, lapack_int ldvt ); lapack_int LAPACKE_zgesdd( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* vt, lapack_int ldvt ); lapack_int LAPACKE_sgesv( int matrix_order, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgesv( int matrix_order, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgesv( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgesv( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_dsgesv( int matrix_order, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb, double* x, lapack_int ldx, lapack_int* iter ); lapack_int LAPACKE_zcgesv( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, lapack_int* iter ); lapack_int LAPACKE_sgesvd( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, float* a, lapack_int lda, float* s, float* u, lapack_int ldu, float* vt, lapack_int ldvt, float* superb ); lapack_int LAPACKE_dgesvd( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, double* a, lapack_int lda, double* s, double* u, lapack_int ldu, double* vt, lapack_int ldvt, double* superb ); lapack_int LAPACKE_cgesvd( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* vt, lapack_int ldvt, float* superb ); lapack_int LAPACKE_zgesvd( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* vt, lapack_int ldvt, double* superb ); lapack_int LAPACKE_sgesvj( int matrix_order, char joba, char jobu, char jobv, lapack_int m, lapack_int n, float* a, lapack_int lda, float* sva, lapack_int mv, float* v, lapack_int ldv, float* stat ); lapack_int LAPACKE_dgesvj( int matrix_order, char joba, char jobu, char jobv, lapack_int m, lapack_int n, double* a, lapack_int lda, double* sva, lapack_int mv, double* v, lapack_int ldv, double* stat ); lapack_int LAPACKE_sgesvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* rpivot ); lapack_int LAPACKE_dgesvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* rpivot ); lapack_int LAPACKE_cgesvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* rpivot ); lapack_int LAPACKE_zgesvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* rpivot ); lapack_int LAPACKE_sgesvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dgesvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_cgesvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zgesvxx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_sgetf2( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_dgetf2( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_cgetf2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_zgetf2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_sgetrf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_dgetrf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_cgetrf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_zgetrf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_sgetri( int matrix_order, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_dgetri( int matrix_order, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_cgetri( int matrix_order, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_zgetri( int matrix_order, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_sgetrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgetrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgetrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgetrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sggbak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* lscale, const float* rscale, lapack_int m, float* v, lapack_int ldv ); lapack_int LAPACKE_dggbak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* lscale, const double* rscale, lapack_int m, double* v, lapack_int ldv ); lapack_int LAPACKE_cggbak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* lscale, const float* rscale, lapack_int m, lapack_complex_float* v, lapack_int ldv ); lapack_int LAPACKE_zggbak( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* lscale, const double* rscale, lapack_int m, lapack_complex_double* v, lapack_int ldv ); lapack_int LAPACKE_sggbal( int matrix_order, char job, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale ); lapack_int LAPACKE_dggbal( int matrix_order, char job, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale ); lapack_int LAPACKE_cggbal( int matrix_order, char job, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale ); lapack_int LAPACKE_zggbal( int matrix_order, char job, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale ); lapack_int LAPACKE_sgges( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_S_SELECT3 selctg, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, lapack_int ldvsl, float* vsr, lapack_int ldvsr ); lapack_int LAPACKE_dgges( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_D_SELECT3 selctg, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, lapack_int ldvsl, double* vsr, lapack_int ldvsr ); lapack_int LAPACKE_cgges( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_C_SELECT2 selctg, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* sdim, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vsl, lapack_int ldvsl, lapack_complex_float* vsr, lapack_int ldvsr ); lapack_int LAPACKE_zgges( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_Z_SELECT2 selctg, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* sdim, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vsl, lapack_int ldvsl, lapack_complex_double* vsr, lapack_int ldvsr ); lapack_int LAPACKE_sggesx( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_S_SELECT3 selctg, char sense, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, lapack_int ldvsl, float* vsr, lapack_int ldvsr, float* rconde, float* rcondv ); lapack_int LAPACKE_dggesx( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_D_SELECT3 selctg, char sense, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, lapack_int ldvsl, double* vsr, lapack_int ldvsr, double* rconde, double* rcondv ); lapack_int LAPACKE_cggesx( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_C_SELECT2 selctg, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* sdim, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vsl, lapack_int ldvsl, lapack_complex_float* vsr, lapack_int ldvsr, float* rconde, float* rcondv ); lapack_int LAPACKE_zggesx( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_Z_SELECT2 selctg, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* sdim, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vsl, lapack_int ldvsl, lapack_complex_double* vsr, lapack_int ldvsr, double* rconde, double* rcondv ); lapack_int LAPACKE_sggev( int matrix_order, char jobvl, char jobvr, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* alphar, float* alphai, float* beta, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr ); lapack_int LAPACKE_dggev( int matrix_order, char jobvl, char jobvr, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* alphar, double* alphai, double* beta, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr ); lapack_int LAPACKE_cggev( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr ); lapack_int LAPACKE_zggev( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr ); lapack_int LAPACKE_sggevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* alphar, float* alphai, float* beta, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* abnrm, float* bbnrm, float* rconde, float* rcondv ); lapack_int LAPACKE_dggevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* alphar, double* alphai, double* beta, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* abnrm, double* bbnrm, double* rconde, double* rcondv ); lapack_int LAPACKE_cggevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* abnrm, float* bbnrm, float* rconde, float* rcondv ); lapack_int LAPACKE_zggevx( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* abnrm, double* bbnrm, double* rconde, double* rcondv ); lapack_int LAPACKE_sggglm( int matrix_order, lapack_int n, lapack_int m, lapack_int p, float* a, lapack_int lda, float* b, lapack_int ldb, float* d, float* x, float* y ); lapack_int LAPACKE_dggglm( int matrix_order, lapack_int n, lapack_int m, lapack_int p, double* a, lapack_int lda, double* b, lapack_int ldb, double* d, double* x, double* y ); lapack_int LAPACKE_cggglm( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* d, lapack_complex_float* x, lapack_complex_float* y ); lapack_int LAPACKE_zggglm( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* d, lapack_complex_double* x, lapack_complex_double* y ); lapack_int LAPACKE_sgghrd( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, float* a, lapack_int lda, float* b, lapack_int ldb, float* q, lapack_int ldq, float* z, lapack_int ldz ); lapack_int LAPACKE_dgghrd( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, double* a, lapack_int lda, double* b, lapack_int ldb, double* q, lapack_int ldq, double* z, lapack_int ldz ); lapack_int LAPACKE_cgghrd( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zgghrd( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_sgglse( int matrix_order, lapack_int m, lapack_int n, lapack_int p, float* a, lapack_int lda, float* b, lapack_int ldb, float* c, float* d, float* x ); lapack_int LAPACKE_dgglse( int matrix_order, lapack_int m, lapack_int n, lapack_int p, double* a, lapack_int lda, double* b, lapack_int ldb, double* c, double* d, double* x ); lapack_int LAPACKE_cgglse( int matrix_order, lapack_int m, lapack_int n, lapack_int p, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* c, lapack_complex_float* d, lapack_complex_float* x ); lapack_int LAPACKE_zgglse( int matrix_order, lapack_int m, lapack_int n, lapack_int p, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* c, lapack_complex_double* d, lapack_complex_double* x ); lapack_int LAPACKE_sggqrf( int matrix_order, lapack_int n, lapack_int m, lapack_int p, float* a, lapack_int lda, float* taua, float* b, lapack_int ldb, float* taub ); lapack_int LAPACKE_dggqrf( int matrix_order, lapack_int n, lapack_int m, lapack_int p, double* a, lapack_int lda, double* taua, double* b, lapack_int ldb, double* taub ); lapack_int LAPACKE_cggqrf( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_float* a, lapack_int lda, lapack_complex_float* taua, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* taub ); lapack_int LAPACKE_zggqrf( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_double* a, lapack_int lda, lapack_complex_double* taua, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* taub ); lapack_int LAPACKE_sggrqf( int matrix_order, lapack_int m, lapack_int p, lapack_int n, float* a, lapack_int lda, float* taua, float* b, lapack_int ldb, float* taub ); lapack_int LAPACKE_dggrqf( int matrix_order, lapack_int m, lapack_int p, lapack_int n, double* a, lapack_int lda, double* taua, double* b, lapack_int ldb, double* taub ); lapack_int LAPACKE_cggrqf( int matrix_order, lapack_int m, lapack_int p, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* taua, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* taub ); lapack_int LAPACKE_zggrqf( int matrix_order, lapack_int m, lapack_int p, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* taua, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* taub ); lapack_int LAPACKE_sggsvd( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, float* a, lapack_int lda, float* b, lapack_int ldb, float* alpha, float* beta, float* u, lapack_int ldu, float* v, lapack_int ldv, float* q, lapack_int ldq, lapack_int* iwork ); lapack_int LAPACKE_dggsvd( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, double* a, lapack_int lda, double* b, lapack_int ldb, double* alpha, double* beta, double* u, lapack_int ldu, double* v, lapack_int ldv, double* q, lapack_int ldq, lapack_int* iwork ); lapack_int LAPACKE_cggsvd( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* alpha, float* beta, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* v, lapack_int ldv, lapack_complex_float* q, lapack_int ldq, lapack_int* iwork ); lapack_int LAPACKE_zggsvd( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* alpha, double* beta, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* v, lapack_int ldv, lapack_complex_double* q, lapack_int ldq, lapack_int* iwork ); lapack_int LAPACKE_sggsvp( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float tola, float tolb, lapack_int* k, lapack_int* l, float* u, lapack_int ldu, float* v, lapack_int ldv, float* q, lapack_int ldq ); lapack_int LAPACKE_dggsvp( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double tola, double tolb, lapack_int* k, lapack_int* l, double* u, lapack_int ldu, double* v, lapack_int ldv, double* q, lapack_int ldq ); lapack_int LAPACKE_cggsvp( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float tola, float tolb, lapack_int* k, lapack_int* l, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* v, lapack_int ldv, lapack_complex_float* q, lapack_int ldq ); lapack_int LAPACKE_zggsvp( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double tola, double tolb, lapack_int* k, lapack_int* l, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* v, lapack_int ldv, lapack_complex_double* q, lapack_int ldq ); lapack_int LAPACKE_sgtcon( char norm, lapack_int n, const float* dl, const float* d, const float* du, const float* du2, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_dgtcon( char norm, lapack_int n, const double* dl, const double* d, const double* du, const double* du2, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_cgtcon( char norm, lapack_int n, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* du2, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_zgtcon( char norm, lapack_int n, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* du2, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_sgtrfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* dl, const float* d, const float* du, const float* dlf, const float* df, const float* duf, const float* du2, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dgtrfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* dl, const double* d, const double* du, const double* dlf, const double* df, const double* duf, const double* du2, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cgtrfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* dlf, const lapack_complex_float* df, const lapack_complex_float* duf, const lapack_complex_float* du2, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zgtrfs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* dlf, const lapack_complex_double* df, const lapack_complex_double* duf, const lapack_complex_double* du2, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sgtsv( int matrix_order, lapack_int n, lapack_int nrhs, float* dl, float* d, float* du, float* b, lapack_int ldb ); lapack_int LAPACKE_dgtsv( int matrix_order, lapack_int n, lapack_int nrhs, double* dl, double* d, double* du, double* b, lapack_int ldb ); lapack_int LAPACKE_cgtsv( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_float* dl, lapack_complex_float* d, lapack_complex_float* du, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgtsv( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_double* dl, lapack_complex_double* d, lapack_complex_double* du, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgtsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dgtsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_cgtsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, lapack_complex_float* dlf, lapack_complex_float* df, lapack_complex_float* duf, lapack_complex_float* du2, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zgtsvx( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, lapack_complex_double* dlf, lapack_complex_double* df, lapack_complex_double* duf, lapack_complex_double* du2, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_sgttrf( lapack_int n, float* dl, float* d, float* du, float* du2, lapack_int* ipiv ); lapack_int LAPACKE_dgttrf( lapack_int n, double* dl, double* d, double* du, double* du2, lapack_int* ipiv ); lapack_int LAPACKE_cgttrf( lapack_int n, lapack_complex_float* dl, lapack_complex_float* d, lapack_complex_float* du, lapack_complex_float* du2, lapack_int* ipiv ); lapack_int LAPACKE_zgttrf( lapack_int n, lapack_complex_double* dl, lapack_complex_double* d, lapack_complex_double* du, lapack_complex_double* du2, lapack_int* ipiv ); lapack_int LAPACKE_sgttrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* dl, const float* d, const float* du, const float* du2, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgttrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* dl, const double* d, const double* du, const double* du2, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgttrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* du2, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgttrs( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* du2, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chbev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhbev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chbevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhbevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chbevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_zhbevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_chbgst( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* bb, lapack_int ldbb, lapack_complex_float* x, lapack_int ldx ); lapack_int LAPACKE_zhbgst( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* bb, lapack_int ldbb, lapack_complex_double* x, lapack_int ldx ); lapack_int LAPACKE_chbgv( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* bb, lapack_int ldbb, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhbgv( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* bb, lapack_int ldbb, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chbgvd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* bb, lapack_int ldbb, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhbgvd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* bb, lapack_int ldbb, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chbgvx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* bb, lapack_int ldbb, lapack_complex_float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_zhbgvx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* bb, lapack_int ldbb, lapack_complex_double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_chbtrd( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, float* d, float* e, lapack_complex_float* q, lapack_int ldq ); lapack_int LAPACKE_zhbtrd( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, double* d, double* e, lapack_complex_double* q, lapack_int ldq ); lapack_int LAPACKE_checon( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_zhecon( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_cheequb( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_zheequb( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_cheev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float* w ); lapack_int LAPACKE_zheev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* w ); lapack_int LAPACKE_cheevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float* w ); lapack_int LAPACKE_zheevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* w ); lapack_int LAPACKE_cheevr( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_zheevr( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_cheevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_zheevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_chegst( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhegst( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chegv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* w ); lapack_int LAPACKE_zhegv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* w ); lapack_int LAPACKE_chegvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* w ); lapack_int LAPACKE_zhegvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* w ); lapack_int LAPACKE_chegvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_zhegvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_cherfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zherfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cherfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const float* s, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zherfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const double* s, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_chesv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhesv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chesvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zhesvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_chesvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zhesvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_chetrd( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float* d, float* e, lapack_complex_float* tau ); lapack_int LAPACKE_zhetrd( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* d, double* e, lapack_complex_double* tau ); lapack_int LAPACKE_chetrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_zhetrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_chetri( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_zhetri( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_chetrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhetrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chfrk( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, float alpha, const lapack_complex_float* a, lapack_int lda, float beta, lapack_complex_float* c ); lapack_int LAPACKE_zhfrk( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, double alpha, const lapack_complex_double* a, lapack_int lda, double beta, lapack_complex_double* c ); lapack_int LAPACKE_shgeqz( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, float* h, lapack_int ldh, float* t, lapack_int ldt, float* alphar, float* alphai, float* beta, float* q, lapack_int ldq, float* z, lapack_int ldz ); lapack_int LAPACKE_dhgeqz( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, double* h, lapack_int ldh, double* t, lapack_int ldt, double* alphar, double* alphai, double* beta, double* q, lapack_int ldq, double* z, lapack_int ldz ); lapack_int LAPACKE_chgeqz( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* h, lapack_int ldh, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhgeqz( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* h, lapack_int ldh, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chpcon( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_zhpcon( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_chpev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhpev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chpevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhpevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chpevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* ap, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_zhpevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* ap, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_chpgst( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_float* ap, const lapack_complex_float* bp ); lapack_int LAPACKE_zhpgst( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_double* ap, const lapack_complex_double* bp ); lapack_int LAPACKE_chpgv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, lapack_complex_float* bp, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhpgv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, lapack_complex_double* bp, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chpgvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, lapack_complex_float* bp, float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhpgvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, lapack_complex_double* bp, double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_chpgvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* ap, lapack_complex_float* bp, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_zhpgvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* ap, lapack_complex_double* bp, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_chprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zhprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_chpsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhpsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chpsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* afp, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zhpsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* afp, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_chptrd( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, float* d, float* e, lapack_complex_float* tau ); lapack_int LAPACKE_zhptrd( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, double* d, double* e, lapack_complex_double* tau ); lapack_int LAPACKE_chptrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, lapack_int* ipiv ); lapack_int LAPACKE_zhptrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, lapack_int* ipiv ); lapack_int LAPACKE_chptri( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, const lapack_int* ipiv ); lapack_int LAPACKE_zhptri( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, const lapack_int* ipiv ); lapack_int LAPACKE_chptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_shsein( int matrix_order, char job, char eigsrc, char initv, lapack_logical* select, lapack_int n, const float* h, lapack_int ldh, float* wr, const float* wi, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_dhsein( int matrix_order, char job, char eigsrc, char initv, lapack_logical* select, lapack_int n, const double* h, lapack_int ldh, double* wr, const double* wi, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_chsein( int matrix_order, char job, char eigsrc, char initv, const lapack_logical* select, lapack_int n, const lapack_complex_float* h, lapack_int ldh, lapack_complex_float* w, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_zhsein( int matrix_order, char job, char eigsrc, char initv, const lapack_logical* select, lapack_int n, const lapack_complex_double* h, lapack_int ldh, lapack_complex_double* w, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_shseqr( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, float* h, lapack_int ldh, float* wr, float* wi, float* z, lapack_int ldz ); lapack_int LAPACKE_dhseqr( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, double* h, lapack_int ldh, double* wr, double* wi, double* z, lapack_int ldz ); lapack_int LAPACKE_chseqr( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* h, lapack_int ldh, lapack_complex_float* w, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zhseqr( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* h, lapack_int ldh, lapack_complex_double* w, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_clacgv( lapack_int n, lapack_complex_float* x, lapack_int incx ); lapack_int LAPACKE_zlacgv( lapack_int n, lapack_complex_double* x, lapack_int incx ); lapack_int LAPACKE_slacn2( lapack_int n, float* v, float* x, lapack_int* isgn, float* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_dlacn2( lapack_int n, double* v, double* x, lapack_int* isgn, double* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_clacn2( lapack_int n, lapack_complex_float* v, lapack_complex_float* x, float* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_zlacn2( lapack_int n, lapack_complex_double* v, lapack_complex_double* x, double* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_slacpy( int matrix_order, char uplo, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dlacpy( int matrix_order, char uplo, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_clacpy( int matrix_order, char uplo, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zlacpy( int matrix_order, char uplo, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_clacp2( int matrix_order, char uplo, lapack_int m, lapack_int n, const float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zlacp2( int matrix_order, char uplo, lapack_int m, lapack_int n, const double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_zlag2c( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_float* sa, lapack_int ldsa ); lapack_int LAPACKE_slag2d( int matrix_order, lapack_int m, lapack_int n, const float* sa, lapack_int ldsa, double* a, lapack_int lda ); lapack_int LAPACKE_dlag2s( int matrix_order, lapack_int m, lapack_int n, const double* a, lapack_int lda, float* sa, lapack_int ldsa ); lapack_int LAPACKE_clag2z( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* sa, lapack_int ldsa, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_slagge( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* d, float* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_dlagge( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* d, double* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_clagge( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* d, lapack_complex_float* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_zlagge( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* d, lapack_complex_double* a, lapack_int lda, lapack_int* iseed ); float LAPACKE_slamch( char cmach ); double LAPACKE_dlamch( char cmach ); float LAPACKE_slange( int matrix_order, char norm, lapack_int m, lapack_int n, const float* a, lapack_int lda ); double LAPACKE_dlange( int matrix_order, char norm, lapack_int m, lapack_int n, const double* a, lapack_int lda ); float LAPACKE_clange( int matrix_order, char norm, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda ); double LAPACKE_zlange( int matrix_order, char norm, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda ); float LAPACKE_clanhe( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda ); double LAPACKE_zlanhe( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda ); float LAPACKE_slansy( int matrix_order, char norm, char uplo, lapack_int n, const float* a, lapack_int lda ); double LAPACKE_dlansy( int matrix_order, char norm, char uplo, lapack_int n, const double* a, lapack_int lda ); float LAPACKE_clansy( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda ); double LAPACKE_zlansy( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda ); float LAPACKE_slantr( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const float* a, lapack_int lda ); double LAPACKE_dlantr( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const double* a, lapack_int lda ); float LAPACKE_clantr( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda ); double LAPACKE_zlantr( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_slarfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* c, lapack_int ldc ); lapack_int LAPACKE_dlarfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* c, lapack_int ldc ); lapack_int LAPACKE_clarfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zlarfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_slarfg( lapack_int n, float* alpha, float* x, lapack_int incx, float* tau ); lapack_int LAPACKE_dlarfg( lapack_int n, double* alpha, double* x, lapack_int incx, double* tau ); lapack_int LAPACKE_clarfg( lapack_int n, lapack_complex_float* alpha, lapack_complex_float* x, lapack_int incx, lapack_complex_float* tau ); lapack_int LAPACKE_zlarfg( lapack_int n, lapack_complex_double* alpha, lapack_complex_double* x, lapack_int incx, lapack_complex_double* tau ); lapack_int LAPACKE_slarft( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const float* v, lapack_int ldv, const float* tau, float* t, lapack_int ldt ); lapack_int LAPACKE_dlarft( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const double* v, lapack_int ldv, const double* tau, double* t, lapack_int ldt ); lapack_int LAPACKE_clarft( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* tau, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zlarft( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* tau, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_slarfx( int matrix_order, char side, lapack_int m, lapack_int n, const float* v, float tau, float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_dlarfx( int matrix_order, char side, lapack_int m, lapack_int n, const double* v, double tau, double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_clarfx( int matrix_order, char side, lapack_int m, lapack_int n, const lapack_complex_float* v, lapack_complex_float tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work ); lapack_int LAPACKE_zlarfx( int matrix_order, char side, lapack_int m, lapack_int n, const lapack_complex_double* v, lapack_complex_double tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work ); lapack_int LAPACKE_slarnv( lapack_int idist, lapack_int* iseed, lapack_int n, float* x ); lapack_int LAPACKE_dlarnv( lapack_int idist, lapack_int* iseed, lapack_int n, double* x ); lapack_int LAPACKE_clarnv( lapack_int idist, lapack_int* iseed, lapack_int n, lapack_complex_float* x ); lapack_int LAPACKE_zlarnv( lapack_int idist, lapack_int* iseed, lapack_int n, lapack_complex_double* x ); lapack_int LAPACKE_slaset( int matrix_order, char uplo, lapack_int m, lapack_int n, float alpha, float beta, float* a, lapack_int lda ); lapack_int LAPACKE_dlaset( int matrix_order, char uplo, lapack_int m, lapack_int n, double alpha, double beta, double* a, lapack_int lda ); lapack_int LAPACKE_claset( int matrix_order, char uplo, lapack_int m, lapack_int n, lapack_complex_float alpha, lapack_complex_float beta, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zlaset( int matrix_order, char uplo, lapack_int m, lapack_int n, lapack_complex_double alpha, lapack_complex_double beta, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_slasrt( char id, lapack_int n, float* d ); lapack_int LAPACKE_dlasrt( char id, lapack_int n, double* d ); lapack_int LAPACKE_slaswp( int matrix_order, lapack_int n, float* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_dlaswp( int matrix_order, lapack_int n, double* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_claswp( int matrix_order, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_zlaswp( int matrix_order, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_slatms( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, float* d, lapack_int mode, float cond, float dmax, lapack_int kl, lapack_int ku, char pack, float* a, lapack_int lda ); lapack_int LAPACKE_dlatms( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, double* d, lapack_int mode, double cond, double dmax, lapack_int kl, lapack_int ku, char pack, double* a, lapack_int lda ); lapack_int LAPACKE_clatms( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, float* d, lapack_int mode, float cond, float dmax, lapack_int kl, lapack_int ku, char pack, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zlatms( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, double* d, lapack_int mode, double cond, double dmax, lapack_int kl, lapack_int ku, char pack, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_slauum( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dlauum( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_clauum( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zlauum( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_sopgtr( int matrix_order, char uplo, lapack_int n, const float* ap, const float* tau, float* q, lapack_int ldq ); lapack_int LAPACKE_dopgtr( int matrix_order, char uplo, lapack_int n, const double* ap, const double* tau, double* q, lapack_int ldq ); lapack_int LAPACKE_sopmtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const float* ap, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dopmtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const double* ap, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sorgbr( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorgbr( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sorghr( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorghr( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sorglq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorglq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sorgql( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorgql( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sorgqr( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorgqr( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sorgrq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorgrq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sorgtr( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const float* tau ); lapack_int LAPACKE_dorgtr( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const double* tau ); lapack_int LAPACKE_sormbr( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormbr( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormhr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormhr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormlq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormlq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormql( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormql( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormqr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormqr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormrq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormrq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormrz( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormrz( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_sormtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc ); lapack_int LAPACKE_dormtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc ); lapack_int LAPACKE_spbcon( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab, float anorm, float* rcond ); lapack_int LAPACKE_dpbcon( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab, double anorm, double* rcond ); lapack_int LAPACKE_cpbcon( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab, float anorm, float* rcond ); lapack_int LAPACKE_zpbcon( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab, double anorm, double* rcond ); lapack_int LAPACKE_spbequ( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab, float* s, float* scond, float* amax ); lapack_int LAPACKE_dpbequ( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab, double* s, double* scond, double* amax ); lapack_int LAPACKE_cpbequ( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab, float* s, float* scond, float* amax ); lapack_int LAPACKE_zpbequ( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab, double* s, double* scond, double* amax ); lapack_int LAPACKE_spbrfs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, const float* afb, lapack_int ldafb, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dpbrfs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, const double* afb, lapack_int ldafb, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cpbrfs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* afb, lapack_int ldafb, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zpbrfs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* afb, lapack_int ldafb, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_spbstf( int matrix_order, char uplo, lapack_int n, lapack_int kb, float* bb, lapack_int ldbb ); lapack_int LAPACKE_dpbstf( int matrix_order, char uplo, lapack_int n, lapack_int kb, double* bb, lapack_int ldbb ); lapack_int LAPACKE_cpbstf( int matrix_order, char uplo, lapack_int n, lapack_int kb, lapack_complex_float* bb, lapack_int ldbb ); lapack_int LAPACKE_zpbstf( int matrix_order, char uplo, lapack_int n, lapack_int kb, lapack_complex_double* bb, lapack_int ldbb ); lapack_int LAPACKE_spbsv( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, float* ab, lapack_int ldab, float* b, lapack_int ldb ); lapack_int LAPACKE_dpbsv( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, double* ab, lapack_int ldab, double* b, lapack_int ldb ); lapack_int LAPACKE_cpbsv( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpbsv( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spbsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, float* ab, lapack_int ldab, float* afb, lapack_int ldafb, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dpbsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, double* ab, lapack_int ldab, double* afb, lapack_int ldafb, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_cpbsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* afb, lapack_int ldafb, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zpbsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* afb, lapack_int ldafb, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_spbtrf( int matrix_order, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab ); lapack_int LAPACKE_dpbtrf( int matrix_order, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab ); lapack_int LAPACKE_cpbtrf( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab ); lapack_int LAPACKE_zpbtrf( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab ); lapack_int LAPACKE_spbtrs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, float* b, lapack_int ldb ); lapack_int LAPACKE_dpbtrs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, double* b, lapack_int ldb ); lapack_int LAPACKE_cpbtrs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpbtrs( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spftrf( int matrix_order, char transr, char uplo, lapack_int n, float* a ); lapack_int LAPACKE_dpftrf( int matrix_order, char transr, char uplo, lapack_int n, double* a ); lapack_int LAPACKE_cpftrf( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_float* a ); lapack_int LAPACKE_zpftrf( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_double* a ); lapack_int LAPACKE_spftri( int matrix_order, char transr, char uplo, lapack_int n, float* a ); lapack_int LAPACKE_dpftri( int matrix_order, char transr, char uplo, lapack_int n, double* a ); lapack_int LAPACKE_cpftri( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_float* a ); lapack_int LAPACKE_zpftri( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_double* a ); lapack_int LAPACKE_spftrs( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const float* a, float* b, lapack_int ldb ); lapack_int LAPACKE_dpftrs( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const double* a, double* b, lapack_int ldb ); lapack_int LAPACKE_cpftrs( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpftrs( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spocon( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, float anorm, float* rcond ); lapack_int LAPACKE_dpocon( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, double anorm, double* rcond ); lapack_int LAPACKE_cpocon( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float anorm, float* rcond ); lapack_int LAPACKE_zpocon( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double anorm, double* rcond ); lapack_int LAPACKE_spoequ( int matrix_order, lapack_int n, const float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_dpoequ( int matrix_order, lapack_int n, const double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_cpoequ( int matrix_order, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_zpoequ( int matrix_order, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_spoequb( int matrix_order, lapack_int n, const float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_dpoequb( int matrix_order, lapack_int n, const double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_cpoequb( int matrix_order, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_zpoequb( int matrix_order, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_sporfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dporfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cporfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zporfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sporfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const float* s, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dporfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const double* s, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_cporfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const float* s, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zporfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const double* s, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_sposv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dposv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_cposv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zposv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_dsposv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* x, lapack_int ldx, lapack_int* iter ); lapack_int LAPACKE_zcposv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, lapack_int* iter ); lapack_int LAPACKE_sposvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dposvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_cposvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zposvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_sposvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dposvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_cposvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zposvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_spotrf( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dpotrf( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_cpotrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zpotrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_spotri( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dpotri( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_cpotri( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zpotri( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_spotrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dpotrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_cpotrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpotrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sppcon( int matrix_order, char uplo, lapack_int n, const float* ap, float anorm, float* rcond ); lapack_int LAPACKE_dppcon( int matrix_order, char uplo, lapack_int n, const double* ap, double anorm, double* rcond ); lapack_int LAPACKE_cppcon( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, float anorm, float* rcond ); lapack_int LAPACKE_zppcon( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, double anorm, double* rcond ); lapack_int LAPACKE_sppequ( int matrix_order, char uplo, lapack_int n, const float* ap, float* s, float* scond, float* amax ); lapack_int LAPACKE_dppequ( int matrix_order, char uplo, lapack_int n, const double* ap, double* s, double* scond, double* amax ); lapack_int LAPACKE_cppequ( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, float* s, float* scond, float* amax ); lapack_int LAPACKE_zppequ( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, double* s, double* scond, double* amax ); lapack_int LAPACKE_spprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, const float* afp, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dpprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, const double* afp, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cpprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zpprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sppsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* ap, float* b, lapack_int ldb ); lapack_int LAPACKE_dppsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* ap, double* b, lapack_int ldb ); lapack_int LAPACKE_cppsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zppsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sppsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* ap, float* afp, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dppsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* ap, double* afp, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_cppsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_complex_float* afp, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zppsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_complex_double* afp, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_spptrf( int matrix_order, char uplo, lapack_int n, float* ap ); lapack_int LAPACKE_dpptrf( int matrix_order, char uplo, lapack_int n, double* ap ); lapack_int LAPACKE_cpptrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap ); lapack_int LAPACKE_zpptrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap ); lapack_int LAPACKE_spptri( int matrix_order, char uplo, lapack_int n, float* ap ); lapack_int LAPACKE_dpptri( int matrix_order, char uplo, lapack_int n, double* ap ); lapack_int LAPACKE_cpptri( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap ); lapack_int LAPACKE_zpptri( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap ); lapack_int LAPACKE_spptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, float* b, lapack_int ldb ); lapack_int LAPACKE_dpptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, double* b, lapack_int ldb ); lapack_int LAPACKE_cpptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spstrf( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, lapack_int* piv, lapack_int* rank, float tol ); lapack_int LAPACKE_dpstrf( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, lapack_int* piv, lapack_int* rank, double tol ); lapack_int LAPACKE_cpstrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* piv, lapack_int* rank, float tol ); lapack_int LAPACKE_zpstrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* piv, lapack_int* rank, double tol ); lapack_int LAPACKE_sptcon( lapack_int n, const float* d, const float* e, float anorm, float* rcond ); lapack_int LAPACKE_dptcon( lapack_int n, const double* d, const double* e, double anorm, double* rcond ); lapack_int LAPACKE_cptcon( lapack_int n, const float* d, const lapack_complex_float* e, float anorm, float* rcond ); lapack_int LAPACKE_zptcon( lapack_int n, const double* d, const lapack_complex_double* e, double anorm, double* rcond ); lapack_int LAPACKE_spteqr( int matrix_order, char compz, lapack_int n, float* d, float* e, float* z, lapack_int ldz ); lapack_int LAPACKE_dpteqr( int matrix_order, char compz, lapack_int n, double* d, double* e, double* z, lapack_int ldz ); lapack_int LAPACKE_cpteqr( int matrix_order, char compz, lapack_int n, float* d, float* e, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zpteqr( int matrix_order, char compz, lapack_int n, double* d, double* e, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_sptrfs( int matrix_order, lapack_int n, lapack_int nrhs, const float* d, const float* e, const float* df, const float* ef, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dptrfs( int matrix_order, lapack_int n, lapack_int nrhs, const double* d, const double* e, const double* df, const double* ef, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_cptrfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* d, const lapack_complex_float* e, const float* df, const lapack_complex_float* ef, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zptrfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* d, const lapack_complex_double* e, const double* df, const lapack_complex_double* ef, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sptsv( int matrix_order, lapack_int n, lapack_int nrhs, float* d, float* e, float* b, lapack_int ldb ); lapack_int LAPACKE_dptsv( int matrix_order, lapack_int n, lapack_int nrhs, double* d, double* e, double* b, lapack_int ldb ); lapack_int LAPACKE_cptsv( int matrix_order, lapack_int n, lapack_int nrhs, float* d, lapack_complex_float* e, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zptsv( int matrix_order, lapack_int n, lapack_int nrhs, double* d, lapack_complex_double* e, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sptsvx( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const float* d, const float* e, float* df, float* ef, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dptsvx( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const double* d, const double* e, double* df, double* ef, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_cptsvx( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const float* d, const lapack_complex_float* e, float* df, lapack_complex_float* ef, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zptsvx( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const double* d, const lapack_complex_double* e, double* df, lapack_complex_double* ef, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_spttrf( lapack_int n, float* d, float* e ); lapack_int LAPACKE_dpttrf( lapack_int n, double* d, double* e ); lapack_int LAPACKE_cpttrf( lapack_int n, float* d, lapack_complex_float* e ); lapack_int LAPACKE_zpttrf( lapack_int n, double* d, lapack_complex_double* e ); lapack_int LAPACKE_spttrs( int matrix_order, lapack_int n, lapack_int nrhs, const float* d, const float* e, float* b, lapack_int ldb ); lapack_int LAPACKE_dpttrs( int matrix_order, lapack_int n, lapack_int nrhs, const double* d, const double* e, double* b, lapack_int ldb ); lapack_int LAPACKE_cpttrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* d, const lapack_complex_float* e, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpttrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* d, const lapack_complex_double* e, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_ssbev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dsbev( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_ssbevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dsbevd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_ssbevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dsbevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_ssbgst( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, const float* bb, lapack_int ldbb, float* x, lapack_int ldx ); lapack_int LAPACKE_dsbgst( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, const double* bb, lapack_int ldbb, double* x, lapack_int ldx ); lapack_int LAPACKE_ssbgv( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, float* bb, lapack_int ldbb, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dsbgv( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, double* bb, lapack_int ldbb, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_ssbgvd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, float* bb, lapack_int ldbb, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dsbgvd( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, double* bb, lapack_int ldbb, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_ssbgvx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, float* bb, lapack_int ldbb, float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dsbgvx( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, double* bb, lapack_int ldbb, double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_ssbtrd( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* d, float* e, float* q, lapack_int ldq ); lapack_int LAPACKE_dsbtrd( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* d, double* e, double* q, lapack_int ldq ); lapack_int LAPACKE_ssfrk( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, float alpha, const float* a, lapack_int lda, float beta, float* c ); lapack_int LAPACKE_dsfrk( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, double alpha, const double* a, lapack_int lda, double beta, double* c ); lapack_int LAPACKE_sspcon( int matrix_order, char uplo, lapack_int n, const float* ap, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_dspcon( int matrix_order, char uplo, lapack_int n, const double* ap, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_cspcon( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_zspcon( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_sspev( int matrix_order, char jobz, char uplo, lapack_int n, float* ap, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dspev( int matrix_order, char jobz, char uplo, lapack_int n, double* ap, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_sspevd( int matrix_order, char jobz, char uplo, lapack_int n, float* ap, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dspevd( int matrix_order, char jobz, char uplo, lapack_int n, double* ap, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_sspevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, float* ap, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dspevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, double* ap, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_sspgst( int matrix_order, lapack_int itype, char uplo, lapack_int n, float* ap, const float* bp ); lapack_int LAPACKE_dspgst( int matrix_order, lapack_int itype, char uplo, lapack_int n, double* ap, const double* bp ); lapack_int LAPACKE_sspgv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* ap, float* bp, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dspgv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* ap, double* bp, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_sspgvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* ap, float* bp, float* w, float* z, lapack_int ldz ); lapack_int LAPACKE_dspgvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* ap, double* bp, double* w, double* z, lapack_int ldz ); lapack_int LAPACKE_sspgvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, float* ap, float* bp, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dspgvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, double* ap, double* bp, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_ssprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, const float* afp, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dsprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, const double* afp, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_csprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zsprfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_sspsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* ap, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dspsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* ap, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cspsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zspsv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sspsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const float* ap, float* afp, lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dspsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const double* ap, double* afp, lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_cspsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* afp, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zspsvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* afp, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_ssptrd( int matrix_order, char uplo, lapack_int n, float* ap, float* d, float* e, float* tau ); lapack_int LAPACKE_dsptrd( int matrix_order, char uplo, lapack_int n, double* ap, double* d, double* e, double* tau ); lapack_int LAPACKE_ssptrf( int matrix_order, char uplo, lapack_int n, float* ap, lapack_int* ipiv ); lapack_int LAPACKE_dsptrf( int matrix_order, char uplo, lapack_int n, double* ap, lapack_int* ipiv ); lapack_int LAPACKE_csptrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, lapack_int* ipiv ); lapack_int LAPACKE_zsptrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, lapack_int* ipiv ); lapack_int LAPACKE_ssptri( int matrix_order, char uplo, lapack_int n, float* ap, const lapack_int* ipiv ); lapack_int LAPACKE_dsptri( int matrix_order, char uplo, lapack_int n, double* ap, const lapack_int* ipiv ); lapack_int LAPACKE_csptri( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, const lapack_int* ipiv ); lapack_int LAPACKE_zsptri( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, const lapack_int* ipiv ); lapack_int LAPACKE_ssptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dsptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_csptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zsptrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sstebz( char range, char order, lapack_int n, float vl, float vu, lapack_int il, lapack_int iu, float abstol, const float* d, const float* e, lapack_int* m, lapack_int* nsplit, float* w, lapack_int* iblock, lapack_int* isplit ); lapack_int LAPACKE_dstebz( char range, char order, lapack_int n, double vl, double vu, lapack_int il, lapack_int iu, double abstol, const double* d, const double* e, lapack_int* m, lapack_int* nsplit, double* w, lapack_int* iblock, lapack_int* isplit ); lapack_int LAPACKE_sstedc( int matrix_order, char compz, lapack_int n, float* d, float* e, float* z, lapack_int ldz ); lapack_int LAPACKE_dstedc( int matrix_order, char compz, lapack_int n, double* d, double* e, double* z, lapack_int ldz ); lapack_int LAPACKE_cstedc( int matrix_order, char compz, lapack_int n, float* d, float* e, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zstedc( int matrix_order, char compz, lapack_int n, double* d, double* e, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_sstegr( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_dstegr( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_cstegr( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_zstegr( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_sstein( int matrix_order, lapack_int n, const float* d, const float* e, lapack_int m, const float* w, const lapack_int* iblock, const lapack_int* isplit, float* z, lapack_int ldz, lapack_int* ifailv ); lapack_int LAPACKE_dstein( int matrix_order, lapack_int n, const double* d, const double* e, lapack_int m, const double* w, const lapack_int* iblock, const lapack_int* isplit, double* z, lapack_int ldz, lapack_int* ifailv ); lapack_int LAPACKE_cstein( int matrix_order, lapack_int n, const float* d, const float* e, lapack_int m, const float* w, const lapack_int* iblock, const lapack_int* isplit, lapack_complex_float* z, lapack_int ldz, lapack_int* ifailv ); lapack_int LAPACKE_zstein( int matrix_order, lapack_int n, const double* d, const double* e, lapack_int m, const double* w, const lapack_int* iblock, const lapack_int* isplit, lapack_complex_double* z, lapack_int ldz, lapack_int* ifailv ); lapack_int LAPACKE_sstemr( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac ); lapack_int LAPACKE_dstemr( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac ); lapack_int LAPACKE_cstemr( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac ); lapack_int LAPACKE_zstemr( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac ); lapack_int LAPACKE_ssteqr( int matrix_order, char compz, lapack_int n, float* d, float* e, float* z, lapack_int ldz ); lapack_int LAPACKE_dsteqr( int matrix_order, char compz, lapack_int n, double* d, double* e, double* z, lapack_int ldz ); lapack_int LAPACKE_csteqr( int matrix_order, char compz, lapack_int n, float* d, float* e, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zsteqr( int matrix_order, char compz, lapack_int n, double* d, double* e, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_ssterf( lapack_int n, float* d, float* e ); lapack_int LAPACKE_dsterf( lapack_int n, double* d, double* e ); lapack_int LAPACKE_sstev( int matrix_order, char jobz, lapack_int n, float* d, float* e, float* z, lapack_int ldz ); lapack_int LAPACKE_dstev( int matrix_order, char jobz, lapack_int n, double* d, double* e, double* z, lapack_int ldz ); lapack_int LAPACKE_sstevd( int matrix_order, char jobz, lapack_int n, float* d, float* e, float* z, lapack_int ldz ); lapack_int LAPACKE_dstevd( int matrix_order, char jobz, lapack_int n, double* d, double* e, double* z, lapack_int ldz ); lapack_int LAPACKE_sstevr( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_dstevr( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_sstevx( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dstevx( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_ssycon( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_dsycon( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_csycon( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, float anorm, float* rcond ); lapack_int LAPACKE_zsycon( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, double anorm, double* rcond ); lapack_int LAPACKE_ssyequb( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_dsyequb( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_csyequb( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_zsyequb( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_ssyev( int matrix_order, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* w ); lapack_int LAPACKE_dsyev( int matrix_order, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* w ); lapack_int LAPACKE_ssyevd( int matrix_order, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* w ); lapack_int LAPACKE_dsyevd( int matrix_order, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* w ); lapack_int LAPACKE_ssyevr( int matrix_order, char jobz, char range, char uplo, lapack_int n, float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_dsyevr( int matrix_order, char jobz, char range, char uplo, lapack_int n, double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz ); lapack_int LAPACKE_ssyevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dsyevx( int matrix_order, char jobz, char range, char uplo, lapack_int n, double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_ssygst( int matrix_order, lapack_int itype, char uplo, lapack_int n, float* a, lapack_int lda, const float* b, lapack_int ldb ); lapack_int LAPACKE_dsygst( int matrix_order, lapack_int itype, char uplo, lapack_int n, double* a, lapack_int lda, const double* b, lapack_int ldb ); lapack_int LAPACKE_ssygv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* w ); lapack_int LAPACKE_dsygv( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* w ); lapack_int LAPACKE_ssygvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* w ); lapack_int LAPACKE_dsygvd( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* w ); lapack_int LAPACKE_ssygvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_dsygvx( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* ifail ); lapack_int LAPACKE_ssyrfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dsyrfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_csyrfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_zsyrfs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_ssyrfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* s, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dsyrfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* s, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_csyrfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const float* s, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zsyrfsx( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const double* s, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_ssysv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dsysv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_csysv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zsysv( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_ssysvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_dsysvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_csysvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr ); lapack_int LAPACKE_zsysvx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr ); lapack_int LAPACKE_ssysvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_dsysvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_csysvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params ); lapack_int LAPACKE_zsysvxx( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params ); lapack_int LAPACKE_ssytrd( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, float* d, float* e, float* tau ); lapack_int LAPACKE_dsytrd( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, double* d, double* e, double* tau ); lapack_int LAPACKE_ssytrf( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_dsytrf( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_csytrf( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_zsytrf( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_ssytri( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_dsytri( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_csytri( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_zsytri( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_ssytrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dsytrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_csytrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zsytrs( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stbcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab, float* rcond ); lapack_int LAPACKE_dtbcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab, double* rcond ); lapack_int LAPACKE_ctbcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab, float* rcond ); lapack_int LAPACKE_ztbcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab, double* rcond ); lapack_int LAPACKE_stbrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, const float* b, lapack_int ldb, const float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dtbrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, const double* b, lapack_int ldb, const double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_ctbrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_ztbrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_stbtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, float* b, lapack_int ldb ); lapack_int LAPACKE_dtbtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, double* b, lapack_int ldb ); lapack_int LAPACKE_ctbtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztbtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stfsm( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, float alpha, const float* a, float* b, lapack_int ldb ); lapack_int LAPACKE_dtfsm( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, double alpha, const double* a, double* b, lapack_int ldb ); lapack_int LAPACKE_ctfsm( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, lapack_complex_float alpha, const lapack_complex_float* a, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztfsm( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, lapack_complex_double alpha, const lapack_complex_double* a, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stftri( int matrix_order, char transr, char uplo, char diag, lapack_int n, float* a ); lapack_int LAPACKE_dtftri( int matrix_order, char transr, char uplo, char diag, lapack_int n, double* a ); lapack_int LAPACKE_ctftri( int matrix_order, char transr, char uplo, char diag, lapack_int n, lapack_complex_float* a ); lapack_int LAPACKE_ztftri( int matrix_order, char transr, char uplo, char diag, lapack_int n, lapack_complex_double* a ); lapack_int LAPACKE_stfttp( int matrix_order, char transr, char uplo, lapack_int n, const float* arf, float* ap ); lapack_int LAPACKE_dtfttp( int matrix_order, char transr, char uplo, lapack_int n, const double* arf, double* ap ); lapack_int LAPACKE_ctfttp( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* arf, lapack_complex_float* ap ); lapack_int LAPACKE_ztfttp( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* arf, lapack_complex_double* ap ); lapack_int LAPACKE_stfttr( int matrix_order, char transr, char uplo, lapack_int n, const float* arf, float* a, lapack_int lda ); lapack_int LAPACKE_dtfttr( int matrix_order, char transr, char uplo, lapack_int n, const double* arf, double* a, lapack_int lda ); lapack_int LAPACKE_ctfttr( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* arf, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_ztfttr( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* arf, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_stgevc( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const float* s, lapack_int lds, const float* p, lapack_int ldp, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_dtgevc( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const double* s, lapack_int lds, const double* p, lapack_int ldp, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ctgevc( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_float* s, lapack_int lds, const lapack_complex_float* p, lapack_int ldp, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ztgevc( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_double* s, lapack_int lds, const lapack_complex_double* p, lapack_int ldp, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_stgexc( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* q, lapack_int ldq, float* z, lapack_int ldz, lapack_int* ifst, lapack_int* ilst ); lapack_int LAPACKE_dtgexc( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* q, lapack_int ldq, double* z, lapack_int ldz, lapack_int* ifst, lapack_int* ilst ); lapack_int LAPACKE_ctgexc( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_ztgexc( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_stgsen( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* alphar, float* alphai, float* beta, float* q, lapack_int ldq, float* z, lapack_int ldz, lapack_int* m, float* pl, float* pr, float* dif ); lapack_int LAPACKE_dtgsen( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* alphar, double* alphai, double* beta, double* q, lapack_int ldq, double* z, lapack_int ldz, lapack_int* m, double* pl, double* pr, double* dif ); lapack_int LAPACKE_ctgsen( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz, lapack_int* m, float* pl, float* pr, float* dif ); lapack_int LAPACKE_ztgsen( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz, lapack_int* m, double* pl, double* pr, double* dif ); lapack_int LAPACKE_stgsja( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, float* a, lapack_int lda, float* b, lapack_int ldb, float tola, float tolb, float* alpha, float* beta, float* u, lapack_int ldu, float* v, lapack_int ldv, float* q, lapack_int ldq, lapack_int* ncycle ); lapack_int LAPACKE_dtgsja( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, double* a, lapack_int lda, double* b, lapack_int ldb, double tola, double tolb, double* alpha, double* beta, double* u, lapack_int ldu, double* v, lapack_int ldv, double* q, lapack_int ldq, lapack_int* ncycle ); lapack_int LAPACKE_ctgsja( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float tola, float tolb, float* alpha, float* beta, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* v, lapack_int ldv, lapack_complex_float* q, lapack_int ldq, lapack_int* ncycle ); lapack_int LAPACKE_ztgsja( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double tola, double tolb, double* alpha, double* beta, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* v, lapack_int ldv, lapack_complex_double* q, lapack_int ldq, lapack_int* ncycle ); lapack_int LAPACKE_stgsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const float* a, lapack_int lda, const float* b, lapack_int ldb, const float* vl, lapack_int ldvl, const float* vr, lapack_int ldvr, float* s, float* dif, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_dtgsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const double* a, lapack_int lda, const double* b, lapack_int ldb, const double* vl, lapack_int ldvl, const double* vr, lapack_int ldvr, double* s, double* dif, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ctgsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* vl, lapack_int ldvl, const lapack_complex_float* vr, lapack_int ldvr, float* s, float* dif, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ztgsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* vl, lapack_int ldvl, const lapack_complex_double* vr, lapack_int ldvr, double* s, double* dif, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_stgsyl( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const float* a, lapack_int lda, const float* b, lapack_int ldb, float* c, lapack_int ldc, const float* d, lapack_int ldd, const float* e, lapack_int lde, float* f, lapack_int ldf, float* scale, float* dif ); lapack_int LAPACKE_dtgsyl( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const double* a, lapack_int lda, const double* b, lapack_int ldb, double* c, lapack_int ldc, const double* d, lapack_int ldd, const double* e, lapack_int lde, double* f, lapack_int ldf, double* scale, double* dif ); lapack_int LAPACKE_ctgsyl( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* c, lapack_int ldc, const lapack_complex_float* d, lapack_int ldd, const lapack_complex_float* e, lapack_int lde, lapack_complex_float* f, lapack_int ldf, float* scale, float* dif ); lapack_int LAPACKE_ztgsyl( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* c, lapack_int ldc, const lapack_complex_double* d, lapack_int ldd, const lapack_complex_double* e, lapack_int lde, lapack_complex_double* f, lapack_int ldf, double* scale, double* dif ); lapack_int LAPACKE_stpcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const float* ap, float* rcond ); lapack_int LAPACKE_dtpcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const double* ap, double* rcond ); lapack_int LAPACKE_ctpcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_float* ap, float* rcond ); lapack_int LAPACKE_ztpcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_double* ap, double* rcond ); lapack_int LAPACKE_stprfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* ap, const float* b, lapack_int ldb, const float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dtprfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* ap, const double* b, lapack_int ldb, const double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_ctprfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_ztprfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_stptri( int matrix_order, char uplo, char diag, lapack_int n, float* ap ); lapack_int LAPACKE_dtptri( int matrix_order, char uplo, char diag, lapack_int n, double* ap ); lapack_int LAPACKE_ctptri( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_float* ap ); lapack_int LAPACKE_ztptri( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_double* ap ); lapack_int LAPACKE_stptrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* ap, float* b, lapack_int ldb ); lapack_int LAPACKE_dtptrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* ap, double* b, lapack_int ldb ); lapack_int LAPACKE_ctptrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztptrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stpttf( int matrix_order, char transr, char uplo, lapack_int n, const float* ap, float* arf ); lapack_int LAPACKE_dtpttf( int matrix_order, char transr, char uplo, lapack_int n, const double* ap, double* arf ); lapack_int LAPACKE_ctpttf( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* ap, lapack_complex_float* arf ); lapack_int LAPACKE_ztpttf( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* ap, lapack_complex_double* arf ); lapack_int LAPACKE_stpttr( int matrix_order, char uplo, lapack_int n, const float* ap, float* a, lapack_int lda ); lapack_int LAPACKE_dtpttr( int matrix_order, char uplo, lapack_int n, const double* ap, double* a, lapack_int lda ); lapack_int LAPACKE_ctpttr( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_ztpttr( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_strcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const float* a, lapack_int lda, float* rcond ); lapack_int LAPACKE_dtrcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const double* a, lapack_int lda, double* rcond ); lapack_int LAPACKE_ctrcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* rcond ); lapack_int LAPACKE_ztrcon( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* rcond ); lapack_int LAPACKE_strevc( int matrix_order, char side, char howmny, lapack_logical* select, lapack_int n, const float* t, lapack_int ldt, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_dtrevc( int matrix_order, char side, char howmny, lapack_logical* select, lapack_int n, const double* t, lapack_int ldt, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ctrevc( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ztrevc( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_strexc( int matrix_order, char compq, lapack_int n, float* t, lapack_int ldt, float* q, lapack_int ldq, lapack_int* ifst, lapack_int* ilst ); lapack_int LAPACKE_dtrexc( int matrix_order, char compq, lapack_int n, double* t, lapack_int ldt, double* q, lapack_int ldq, lapack_int* ifst, lapack_int* ilst ); lapack_int LAPACKE_ctrexc( int matrix_order, char compq, lapack_int n, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* q, lapack_int ldq, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_ztrexc( int matrix_order, char compq, lapack_int n, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* q, lapack_int ldq, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_strrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* b, lapack_int ldb, const float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_dtrrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* b, lapack_int ldb, const double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_ctrrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr ); lapack_int LAPACKE_ztrrfs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr ); lapack_int LAPACKE_strsen( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, float* t, lapack_int ldt, float* q, lapack_int ldq, float* wr, float* wi, lapack_int* m, float* s, float* sep ); lapack_int LAPACKE_dtrsen( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, double* t, lapack_int ldt, double* q, lapack_int ldq, double* wr, double* wi, lapack_int* m, double* s, double* sep ); lapack_int LAPACKE_ctrsen( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* w, lapack_int* m, float* s, float* sep ); lapack_int LAPACKE_ztrsen( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* w, lapack_int* m, double* s, double* sep ); lapack_int LAPACKE_strsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const float* t, lapack_int ldt, const float* vl, lapack_int ldvl, const float* vr, lapack_int ldvr, float* s, float* sep, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_dtrsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const double* t, lapack_int ldt, const double* vl, lapack_int ldvl, const double* vr, lapack_int ldvr, double* s, double* sep, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ctrsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_float* t, lapack_int ldt, const lapack_complex_float* vl, lapack_int ldvl, const lapack_complex_float* vr, lapack_int ldvr, float* s, float* sep, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_ztrsna( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_double* t, lapack_int ldt, const lapack_complex_double* vl, lapack_int ldvl, const lapack_complex_double* vr, lapack_int ldvr, double* s, double* sep, lapack_int mm, lapack_int* m ); lapack_int LAPACKE_strsyl( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const float* a, lapack_int lda, const float* b, lapack_int ldb, float* c, lapack_int ldc, float* scale ); lapack_int LAPACKE_dtrsyl( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const double* a, lapack_int lda, const double* b, lapack_int ldb, double* c, lapack_int ldc, double* scale ); lapack_int LAPACKE_ctrsyl( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* c, lapack_int ldc, float* scale ); lapack_int LAPACKE_ztrsyl( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* c, lapack_int ldc, double* scale ); lapack_int LAPACKE_strtri( int matrix_order, char uplo, char diag, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dtrtri( int matrix_order, char uplo, char diag, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_ctrtri( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_ztrtri( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_strtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dtrtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_ctrtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztrtrs( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_strttf( int matrix_order, char transr, char uplo, lapack_int n, const float* a, lapack_int lda, float* arf ); lapack_int LAPACKE_dtrttf( int matrix_order, char transr, char uplo, lapack_int n, const double* a, lapack_int lda, double* arf ); lapack_int LAPACKE_ctrttf( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* arf ); lapack_int LAPACKE_ztrttf( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* arf ); lapack_int LAPACKE_strttp( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, float* ap ); lapack_int LAPACKE_dtrttp( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, double* ap ); lapack_int LAPACKE_ctrttp( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* ap ); lapack_int LAPACKE_ztrttp( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* ap ); lapack_int LAPACKE_stzrzf( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau ); lapack_int LAPACKE_dtzrzf( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau ); lapack_int LAPACKE_ctzrzf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau ); lapack_int LAPACKE_ztzrzf( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau ); lapack_int LAPACKE_cungbr( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zungbr( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cunghr( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zunghr( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cunglq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zunglq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cungql( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zungql( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cungqr( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zungqr( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cungrq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zungrq( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cungtr( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau ); lapack_int LAPACKE_zungtr( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau ); lapack_int LAPACKE_cunmbr( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmbr( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmhr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmhr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmlq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmlq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmql( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmql( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmqr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmqr( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmrq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmrq( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmrz( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmrz( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cunmtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zunmtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_cupgtr( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, const lapack_complex_float* tau, lapack_complex_float* q, lapack_int ldq ); lapack_int LAPACKE_zupgtr( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, const lapack_complex_double* tau, lapack_complex_double* q, lapack_int ldq ); lapack_int LAPACKE_cupmtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_float* ap, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zupmtr( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_double* ap, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_sbdsdc_work( int matrix_order, char uplo, char compq, lapack_int n, float* d, float* e, float* u, lapack_int ldu, float* vt, lapack_int ldvt, float* q, lapack_int* iq, float* work, lapack_int* iwork ); lapack_int LAPACKE_dbdsdc_work( int matrix_order, char uplo, char compq, lapack_int n, double* d, double* e, double* u, lapack_int ldu, double* vt, lapack_int ldvt, double* q, lapack_int* iq, double* work, lapack_int* iwork ); lapack_int LAPACKE_sbdsqr_work( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, float* d, float* e, float* vt, lapack_int ldvt, float* u, lapack_int ldu, float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_dbdsqr_work( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, double* d, double* e, double* vt, lapack_int ldvt, double* u, lapack_int ldu, double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_cbdsqr_work( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, float* d, float* e, lapack_complex_float* vt, lapack_int ldvt, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_zbdsqr_work( int matrix_order, char uplo, lapack_int n, lapack_int ncvt, lapack_int nru, lapack_int ncc, double* d, double* e, lapack_complex_double* vt, lapack_int ldvt, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_sdisna_work( char job, lapack_int m, lapack_int n, const float* d, float* sep ); lapack_int LAPACKE_ddisna_work( char job, lapack_int m, lapack_int n, const double* d, double* sep ); lapack_int LAPACKE_sgbbrd_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, float* ab, lapack_int ldab, float* d, float* e, float* q, lapack_int ldq, float* pt, lapack_int ldpt, float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_dgbbrd_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, double* ab, lapack_int ldab, double* d, double* e, double* q, lapack_int ldq, double* pt, lapack_int ldpt, double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_cgbbrd_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, lapack_complex_float* ab, lapack_int ldab, float* d, float* e, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* pt, lapack_int ldpt, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgbbrd_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int ncc, lapack_int kl, lapack_int ku, lapack_complex_double* ab, lapack_int ldab, double* d, double* e, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* pt, lapack_int ldpt, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgbcon_work( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const float* ab, lapack_int ldab, const lapack_int* ipiv, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgbcon_work( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const double* ab, lapack_int ldab, const lapack_int* ipiv, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgbcon_work( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float* ab, lapack_int ldab, const lapack_int* ipiv, float anorm, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgbcon_work( int matrix_order, char norm, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double* ab, lapack_int ldab, const lapack_int* ipiv, double anorm, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgbequ_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgbequ_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgbequ_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgbequ_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgbequb_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgbequb_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgbequb_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float* ab, lapack_int ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgbequb_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double* ab, lapack_int ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgbrfs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const float* ab, lapack_int ldab, const float* afb, lapack_int ldafb, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgbrfs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const double* ab, lapack_int ldab, const double* afb, lapack_int ldafb, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgbrfs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* afb, lapack_int ldafb, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgbrfs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* afb, lapack_int ldafb, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgbrfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const float* ab, lapack_int ldab, const float* afb, lapack_int ldafb, const lapack_int* ipiv, const float* r, const float* c, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgbrfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const double* ab, lapack_int ldab, const double* afb, lapack_int ldafb, const lapack_int* ipiv, const double* r, const double* c, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgbrfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* afb, lapack_int ldafb, const lapack_int* ipiv, const float* r, const float* c, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgbrfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* afb, lapack_int ldafb, const lapack_int* ipiv, const double* r, const double* c, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgbsv_work( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, float* ab, lapack_int ldab, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgbsv_work( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, double* ab, lapack_int ldab, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgbsv_work( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgbsv_work( int matrix_order, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgbsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, float* ab, lapack_int ldab, float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgbsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, double* ab, lapack_int ldab, double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgbsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgbsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgbsvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, float* ab, lapack_int ldab, float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgbsvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, double* ab, lapack_int ldab, double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgbsvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgbsvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* afb, lapack_int ldafb, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgbtrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, float* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_dgbtrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, double* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_cgbtrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, lapack_complex_float* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_zgbtrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, lapack_complex_double* ab, lapack_int ldab, lapack_int* ipiv ); lapack_int LAPACKE_sgbtrs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const float* ab, lapack_int ldab, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgbtrs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const double* ab, lapack_int ldab, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgbtrs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgbtrs_work( int matrix_order, char trans, lapack_int n, lapack_int kl, lapack_int ku, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgebak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* scale, lapack_int m, float* v, lapack_int ldv ); lapack_int LAPACKE_dgebak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* scale, lapack_int m, double* v, lapack_int ldv ); lapack_int LAPACKE_cgebak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* scale, lapack_int m, lapack_complex_float* v, lapack_int ldv ); lapack_int LAPACKE_zgebak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* scale, lapack_int m, lapack_complex_double* v, lapack_int ldv ); lapack_int LAPACKE_sgebal_work( int matrix_order, char job, lapack_int n, float* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, float* scale ); lapack_int LAPACKE_dgebal_work( int matrix_order, char job, lapack_int n, double* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, double* scale ); lapack_int LAPACKE_cgebal_work( int matrix_order, char job, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, float* scale ); lapack_int LAPACKE_zgebal_work( int matrix_order, char job, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ilo, lapack_int* ihi, double* scale ); lapack_int LAPACKE_sgebrd_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* d, float* e, float* tauq, float* taup, float* work, lapack_int lwork ); lapack_int LAPACKE_dgebrd_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* d, double* e, double* tauq, double* taup, double* work, lapack_int lwork ); lapack_int LAPACKE_cgebrd_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* d, float* e, lapack_complex_float* tauq, lapack_complex_float* taup, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgebrd_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* d, double* e, lapack_complex_double* tauq, lapack_complex_double* taup, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgecon_work( int matrix_order, char norm, lapack_int n, const float* a, lapack_int lda, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgecon_work( int matrix_order, char norm, lapack_int n, const double* a, lapack_int lda, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgecon_work( int matrix_order, char norm, lapack_int n, const lapack_complex_float* a, lapack_int lda, float anorm, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgecon_work( int matrix_order, char norm, lapack_int n, const lapack_complex_double* a, lapack_int lda, double anorm, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgeequ_work( int matrix_order, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgeequ_work( int matrix_order, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgeequ_work( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgeequ_work( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgeequb_work( int matrix_order, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_dgeequb_work( int matrix_order, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_cgeequb_work( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax ); lapack_int LAPACKE_zgeequb_work( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax ); lapack_int LAPACKE_sgees_work( int matrix_order, char jobvs, char sort, LAPACK_S_SELECT2 select, lapack_int n, float* a, lapack_int lda, lapack_int* sdim, float* wr, float* wi, float* vs, lapack_int ldvs, float* work, lapack_int lwork, lapack_logical* bwork ); lapack_int LAPACKE_dgees_work( int matrix_order, char jobvs, char sort, LAPACK_D_SELECT2 select, lapack_int n, double* a, lapack_int lda, lapack_int* sdim, double* wr, double* wi, double* vs, lapack_int ldvs, double* work, lapack_int lwork, lapack_logical* bwork ); lapack_int LAPACKE_cgees_work( int matrix_order, char jobvs, char sort, LAPACK_C_SELECT1 select, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* sdim, lapack_complex_float* w, lapack_complex_float* vs, lapack_int ldvs, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_logical* bwork ); lapack_int LAPACKE_zgees_work( int matrix_order, char jobvs, char sort, LAPACK_Z_SELECT1 select, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* sdim, lapack_complex_double* w, lapack_complex_double* vs, lapack_int ldvs, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_logical* bwork ); lapack_int LAPACKE_sgeesx_work( int matrix_order, char jobvs, char sort, LAPACK_S_SELECT2 select, char sense, lapack_int n, float* a, lapack_int lda, lapack_int* sdim, float* wr, float* wi, float* vs, lapack_int ldvs, float* rconde, float* rcondv, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork, lapack_logical* bwork ); lapack_int LAPACKE_dgeesx_work( int matrix_order, char jobvs, char sort, LAPACK_D_SELECT2 select, char sense, lapack_int n, double* a, lapack_int lda, lapack_int* sdim, double* wr, double* wi, double* vs, lapack_int ldvs, double* rconde, double* rcondv, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork, lapack_logical* bwork ); lapack_int LAPACKE_cgeesx_work( int matrix_order, char jobvs, char sort, LAPACK_C_SELECT1 select, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* sdim, lapack_complex_float* w, lapack_complex_float* vs, lapack_int ldvs, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_logical* bwork ); lapack_int LAPACKE_zgeesx_work( int matrix_order, char jobvs, char sort, LAPACK_Z_SELECT1 select, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* sdim, lapack_complex_double* w, lapack_complex_double* vs, lapack_int ldvs, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_logical* bwork ); lapack_int LAPACKE_sgeev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, float* a, lapack_int lda, float* wr, float* wi, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, float* work, lapack_int lwork ); lapack_int LAPACKE_dgeev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, double* a, lapack_int lda, double* wr, double* wi, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, double* work, lapack_int lwork ); lapack_int LAPACKE_cgeev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* w, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zgeev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* w, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sgeevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, float* a, lapack_int lda, float* wr, float* wi, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dgeevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, double* a, lapack_int lda, double* wr, double* wi, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_cgeevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* w, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zgeevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* w, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sgehrd_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgehrd_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgehrd_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgehrd_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgejsv_work( int matrix_order, char joba, char jobu, char jobv, char jobr, char jobt, char jobp, lapack_int m, lapack_int n, float* a, lapack_int lda, float* sva, float* u, lapack_int ldu, float* v, lapack_int ldv, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dgejsv_work( int matrix_order, char joba, char jobu, char jobv, char jobr, char jobt, char jobp, lapack_int m, lapack_int n, double* a, lapack_int lda, double* sva, double* u, lapack_int ldu, double* v, lapack_int ldv, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_sgelq2_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work ); lapack_int LAPACKE_dgelq2_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work ); lapack_int LAPACKE_cgelq2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work ); lapack_int LAPACKE_zgelq2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work ); lapack_int LAPACKE_sgelqf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgelqf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgelqf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgelqf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgels_work( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, float* work, lapack_int lwork ); lapack_int LAPACKE_dgels_work( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* work, lapack_int lwork ); lapack_int LAPACKE_cgels_work( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgels_work( int matrix_order, char trans, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgelsd_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dgelsd_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_cgelsd_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork ); lapack_int LAPACKE_zgelsd_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork ); lapack_int LAPACKE_sgelss_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank, float* work, lapack_int lwork ); lapack_int LAPACKE_dgelss_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank, double* work, lapack_int lwork ); lapack_int LAPACKE_cgelss_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* s, float rcond, lapack_int* rank, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zgelss_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* s, double rcond, lapack_int* rank, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sgelsy_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* jpvt, float rcond, lapack_int* rank, float* work, lapack_int lwork ); lapack_int LAPACKE_dgelsy_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* jpvt, double rcond, lapack_int* rank, double* work, lapack_int lwork ); lapack_int LAPACKE_cgelsy_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* jpvt, float rcond, lapack_int* rank, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zgelsy_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* jpvt, double rcond, lapack_int* rank, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sgeqlf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgeqlf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgeqlf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgeqlf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgeqp3_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* jpvt, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgeqp3_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* jpvt, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgeqp3_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* jpvt, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zgeqp3_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* jpvt, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sgeqpf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* jpvt, float* tau, float* work ); lapack_int LAPACKE_dgeqpf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* jpvt, double* tau, double* work ); lapack_int LAPACKE_cgeqpf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* jpvt, lapack_complex_float* tau, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgeqpf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* jpvt, lapack_complex_double* tau, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgeqr2_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work ); lapack_int LAPACKE_dgeqr2_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work ); lapack_int LAPACKE_cgeqr2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work ); lapack_int LAPACKE_zgeqr2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work ); lapack_int LAPACKE_sgeqrf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgeqrf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgeqrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgeqrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgeqrfp_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgeqrfp_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgeqrfp_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgeqrfp_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgerfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgerfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgerfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgerfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgerfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* r, const float* c, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgerfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* r, const double* c, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgerfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const float* r, const float* c, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgerfsx_work( int matrix_order, char trans, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const double* r, const double* c, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgerqf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dgerqf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_cgerqf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgerqf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgesdd_work( int matrix_order, char jobz, lapack_int m, lapack_int n, float* a, lapack_int lda, float* s, float* u, lapack_int ldu, float* vt, lapack_int ldvt, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dgesdd_work( int matrix_order, char jobz, lapack_int m, lapack_int n, double* a, lapack_int lda, double* s, double* u, lapack_int ldu, double* vt, lapack_int ldvt, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_cgesdd_work( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* vt, lapack_int ldvt, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork ); lapack_int LAPACKE_zgesdd_work( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* vt, lapack_int ldvt, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork ); lapack_int LAPACKE_sgesv_work( int matrix_order, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgesv_work( int matrix_order, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgesv_work( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgesv_work( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_dsgesv_work( int matrix_order, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb, double* x, lapack_int ldx, double* work, float* swork, lapack_int* iter ); lapack_int LAPACKE_zcgesv_work( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, lapack_complex_double* work, lapack_complex_float* swork, double* rwork, lapack_int* iter ); lapack_int LAPACKE_sgesvd_work( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, float* a, lapack_int lda, float* s, float* u, lapack_int ldu, float* vt, lapack_int ldvt, float* work, lapack_int lwork ); lapack_int LAPACKE_dgesvd_work( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, double* a, lapack_int lda, double* s, double* u, lapack_int ldu, double* vt, lapack_int ldvt, double* work, lapack_int lwork ); lapack_int LAPACKE_cgesvd_work( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* vt, lapack_int ldvt, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zgesvd_work( int matrix_order, char jobu, char jobvt, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* vt, lapack_int ldvt, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sgesvj_work( int matrix_order, char joba, char jobu, char jobv, lapack_int m, lapack_int n, float* a, lapack_int lda, float* sva, lapack_int mv, float* v, lapack_int ldv, float* work, lapack_int lwork ); lapack_int LAPACKE_dgesvj_work( int matrix_order, char joba, char jobu, char jobv, lapack_int m, lapack_int n, double* a, lapack_int lda, double* sva, lapack_int mv, double* v, lapack_int ldv, double* work, lapack_int lwork ); lapack_int LAPACKE_sgesvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgesvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgesvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgesvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgesvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgesvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgesvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgesvxx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgetf2_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_dgetf2_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_cgetf2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_zgetf2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_sgetrf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_dgetrf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_cgetrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_zgetrf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv ); lapack_int LAPACKE_sgetri_work( int matrix_order, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv, float* work, lapack_int lwork ); lapack_int LAPACKE_dgetri_work( int matrix_order, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv, double* work, lapack_int lwork ); lapack_int LAPACKE_cgetri_work( int matrix_order, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgetri_work( int matrix_order, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgetrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgetrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgetrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgetrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sggbak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* lscale, const float* rscale, lapack_int m, float* v, lapack_int ldv ); lapack_int LAPACKE_dggbak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* lscale, const double* rscale, lapack_int m, double* v, lapack_int ldv ); lapack_int LAPACKE_cggbak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const float* lscale, const float* rscale, lapack_int m, lapack_complex_float* v, lapack_int ldv ); lapack_int LAPACKE_zggbak_work( int matrix_order, char job, char side, lapack_int n, lapack_int ilo, lapack_int ihi, const double* lscale, const double* rscale, lapack_int m, lapack_complex_double* v, lapack_int ldv ); lapack_int LAPACKE_sggbal_work( int matrix_order, char job, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* work ); lapack_int LAPACKE_dggbal_work( int matrix_order, char job, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* work ); lapack_int LAPACKE_cggbal_work( int matrix_order, char job, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* work ); lapack_int LAPACKE_zggbal_work( int matrix_order, char job, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* work ); lapack_int LAPACKE_sgges_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_S_SELECT3 selctg, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, lapack_int ldvsl, float* vsr, lapack_int ldvsr, float* work, lapack_int lwork, lapack_logical* bwork ); lapack_int LAPACKE_dgges_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_D_SELECT3 selctg, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, lapack_int ldvsl, double* vsr, lapack_int ldvsr, double* work, lapack_int lwork, lapack_logical* bwork ); lapack_int LAPACKE_cgges_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_C_SELECT2 selctg, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* sdim, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vsl, lapack_int ldvsl, lapack_complex_float* vsr, lapack_int ldvsr, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_logical* bwork ); lapack_int LAPACKE_zgges_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_Z_SELECT2 selctg, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* sdim, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vsl, lapack_int ldvsl, lapack_complex_double* vsr, lapack_int ldvsr, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_logical* bwork ); lapack_int LAPACKE_sggesx_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_S_SELECT3 selctg, char sense, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, lapack_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, lapack_int ldvsl, float* vsr, lapack_int ldvsr, float* rconde, float* rcondv, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork, lapack_logical* bwork ); lapack_int LAPACKE_dggesx_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_D_SELECT3 selctg, char sense, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, lapack_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, lapack_int ldvsl, double* vsr, lapack_int ldvsr, double* rconde, double* rcondv, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork, lapack_logical* bwork ); lapack_int LAPACKE_cggesx_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_C_SELECT2 selctg, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_int* sdim, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vsl, lapack_int ldvsl, lapack_complex_float* vsr, lapack_int ldvsr, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork, lapack_int liwork, lapack_logical* bwork ); lapack_int LAPACKE_zggesx_work( int matrix_order, char jobvsl, char jobvsr, char sort, LAPACK_Z_SELECT2 selctg, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_int* sdim, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vsl, lapack_int ldvsl, lapack_complex_double* vsr, lapack_int ldvsr, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork, lapack_int liwork, lapack_logical* bwork ); lapack_int LAPACKE_sggev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* alphar, float* alphai, float* beta, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, float* work, lapack_int lwork ); lapack_int LAPACKE_dggev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* alphar, double* alphai, double* beta, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, double* work, lapack_int lwork ); lapack_int LAPACKE_cggev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zggev_work( int matrix_order, char jobvl, char jobvr, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_sggevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* alphar, float* alphai, float* beta, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* abnrm, float* bbnrm, float* rconde, float* rcondv, float* work, lapack_int lwork, lapack_int* iwork, lapack_logical* bwork ); lapack_int LAPACKE_dggevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* alphar, double* alphai, double* beta, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* abnrm, double* bbnrm, double* rconde, double* rcondv, double* work, lapack_int lwork, lapack_int* iwork, lapack_logical* bwork ); lapack_int LAPACKE_cggevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* abnrm, float* bbnrm, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork, lapack_logical* bwork ); lapack_int LAPACKE_zggevx_work( int matrix_order, char balanc, char jobvl, char jobvr, char sense, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* abnrm, double* bbnrm, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork, lapack_logical* bwork ); lapack_int LAPACKE_sggglm_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, float* a, lapack_int lda, float* b, lapack_int ldb, float* d, float* x, float* y, float* work, lapack_int lwork ); lapack_int LAPACKE_dggglm_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, double* a, lapack_int lda, double* b, lapack_int ldb, double* d, double* x, double* y, double* work, lapack_int lwork ); lapack_int LAPACKE_cggglm_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* d, lapack_complex_float* x, lapack_complex_float* y, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zggglm_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* d, lapack_complex_double* x, lapack_complex_double* y, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sgghrd_work( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, float* a, lapack_int lda, float* b, lapack_int ldb, float* q, lapack_int ldq, float* z, lapack_int ldz ); lapack_int LAPACKE_dgghrd_work( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, double* a, lapack_int lda, double* b, lapack_int ldb, double* q, lapack_int ldq, double* z, lapack_int ldz ); lapack_int LAPACKE_cgghrd_work( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz ); lapack_int LAPACKE_zgghrd_work( int matrix_order, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz ); lapack_int LAPACKE_sgglse_work( int matrix_order, lapack_int m, lapack_int n, lapack_int p, float* a, lapack_int lda, float* b, lapack_int ldb, float* c, float* d, float* x, float* work, lapack_int lwork ); lapack_int LAPACKE_dgglse_work( int matrix_order, lapack_int m, lapack_int n, lapack_int p, double* a, lapack_int lda, double* b, lapack_int ldb, double* c, double* d, double* x, double* work, lapack_int lwork ); lapack_int LAPACKE_cgglse_work( int matrix_order, lapack_int m, lapack_int n, lapack_int p, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* c, lapack_complex_float* d, lapack_complex_float* x, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zgglse_work( int matrix_order, lapack_int m, lapack_int n, lapack_int p, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* c, lapack_complex_double* d, lapack_complex_double* x, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sggqrf_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, float* a, lapack_int lda, float* taua, float* b, lapack_int ldb, float* taub, float* work, lapack_int lwork ); lapack_int LAPACKE_dggqrf_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, double* a, lapack_int lda, double* taua, double* b, lapack_int ldb, double* taub, double* work, lapack_int lwork ); lapack_int LAPACKE_cggqrf_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_float* a, lapack_int lda, lapack_complex_float* taua, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* taub, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zggqrf_work( int matrix_order, lapack_int n, lapack_int m, lapack_int p, lapack_complex_double* a, lapack_int lda, lapack_complex_double* taua, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* taub, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sggrqf_work( int matrix_order, lapack_int m, lapack_int p, lapack_int n, float* a, lapack_int lda, float* taua, float* b, lapack_int ldb, float* taub, float* work, lapack_int lwork ); lapack_int LAPACKE_dggrqf_work( int matrix_order, lapack_int m, lapack_int p, lapack_int n, double* a, lapack_int lda, double* taua, double* b, lapack_int ldb, double* taub, double* work, lapack_int lwork ); lapack_int LAPACKE_cggrqf_work( int matrix_order, lapack_int m, lapack_int p, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* taua, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* taub, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zggrqf_work( int matrix_order, lapack_int m, lapack_int p, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* taua, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* taub, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_sggsvd_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, float* a, lapack_int lda, float* b, lapack_int ldb, float* alpha, float* beta, float* u, lapack_int ldu, float* v, lapack_int ldv, float* q, lapack_int ldq, float* work, lapack_int* iwork ); lapack_int LAPACKE_dggsvd_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, double* a, lapack_int lda, double* b, lapack_int ldb, double* alpha, double* beta, double* u, lapack_int ldu, double* v, lapack_int ldv, double* q, lapack_int ldq, double* work, lapack_int* iwork ); lapack_int LAPACKE_cggsvd_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* alpha, float* beta, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* v, lapack_int ldv, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* work, float* rwork, lapack_int* iwork ); lapack_int LAPACKE_zggsvd_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int n, lapack_int p, lapack_int* k, lapack_int* l, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* alpha, double* beta, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* v, lapack_int ldv, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* work, double* rwork, lapack_int* iwork ); lapack_int LAPACKE_sggsvp_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float tola, float tolb, lapack_int* k, lapack_int* l, float* u, lapack_int ldu, float* v, lapack_int ldv, float* q, lapack_int ldq, lapack_int* iwork, float* tau, float* work ); lapack_int LAPACKE_dggsvp_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double tola, double tolb, lapack_int* k, lapack_int* l, double* u, lapack_int ldu, double* v, lapack_int ldv, double* q, lapack_int ldq, lapack_int* iwork, double* tau, double* work ); lapack_int LAPACKE_cggsvp_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float tola, float tolb, lapack_int* k, lapack_int* l, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* v, lapack_int ldv, lapack_complex_float* q, lapack_int ldq, lapack_int* iwork, float* rwork, lapack_complex_float* tau, lapack_complex_float* work ); lapack_int LAPACKE_zggsvp_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double tola, double tolb, lapack_int* k, lapack_int* l, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* v, lapack_int ldv, lapack_complex_double* q, lapack_int ldq, lapack_int* iwork, double* rwork, lapack_complex_double* tau, lapack_complex_double* work ); lapack_int LAPACKE_sgtcon_work( char norm, lapack_int n, const float* dl, const float* d, const float* du, const float* du2, const lapack_int* ipiv, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgtcon_work( char norm, lapack_int n, const double* dl, const double* d, const double* du, const double* du2, const lapack_int* ipiv, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgtcon_work( char norm, lapack_int n, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* du2, const lapack_int* ipiv, float anorm, float* rcond, lapack_complex_float* work ); lapack_int LAPACKE_zgtcon_work( char norm, lapack_int n, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* du2, const lapack_int* ipiv, double anorm, double* rcond, lapack_complex_double* work ); lapack_int LAPACKE_sgtrfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* dl, const float* d, const float* du, const float* dlf, const float* df, const float* duf, const float* du2, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgtrfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* dl, const double* d, const double* du, const double* dlf, const double* df, const double* duf, const double* du2, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgtrfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* dlf, const lapack_complex_float* df, const lapack_complex_float* duf, const lapack_complex_float* du2, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgtrfs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* dlf, const lapack_complex_double* df, const lapack_complex_double* duf, const lapack_complex_double* du2, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgtsv_work( int matrix_order, lapack_int n, lapack_int nrhs, float* dl, float* d, float* du, float* b, lapack_int ldb ); lapack_int LAPACKE_dgtsv_work( int matrix_order, lapack_int n, lapack_int nrhs, double* dl, double* d, double* du, double* b, lapack_int ldb ); lapack_int LAPACKE_cgtsv_work( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_float* dl, lapack_complex_float* d, lapack_complex_float* du, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgtsv_work( int matrix_order, lapack_int n, lapack_int nrhs, lapack_complex_double* dl, lapack_complex_double* d, lapack_complex_double* du, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgtsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dgtsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cgtsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, lapack_complex_float* dlf, lapack_complex_float* df, lapack_complex_float* duf, lapack_complex_float* du2, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zgtsvx_work( int matrix_order, char fact, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, lapack_complex_double* dlf, lapack_complex_double* df, lapack_complex_double* duf, lapack_complex_double* du2, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sgttrf_work( lapack_int n, float* dl, float* d, float* du, float* du2, lapack_int* ipiv ); lapack_int LAPACKE_dgttrf_work( lapack_int n, double* dl, double* d, double* du, double* du2, lapack_int* ipiv ); lapack_int LAPACKE_cgttrf_work( lapack_int n, lapack_complex_float* dl, lapack_complex_float* d, lapack_complex_float* du, lapack_complex_float* du2, lapack_int* ipiv ); lapack_int LAPACKE_zgttrf_work( lapack_int n, lapack_complex_double* dl, lapack_complex_double* d, lapack_complex_double* du, lapack_complex_double* du2, lapack_int* ipiv ); lapack_int LAPACKE_sgttrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const float* dl, const float* d, const float* du, const float* du2, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dgttrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const double* dl, const double* d, const double* du, const double* du2, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cgttrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* du2, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zgttrs_work( int matrix_order, char trans, lapack_int n, lapack_int nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* du2, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chbev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhbev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chbevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zhbevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_chbevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_zhbevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_chbgst_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* bb, lapack_int ldbb, lapack_complex_float* x, lapack_int ldx, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhbgst_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* bb, lapack_int ldbb, lapack_complex_double* x, lapack_int ldx, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chbgv_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* bb, lapack_int ldbb, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhbgv_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* bb, lapack_int ldbb, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chbgvd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* bb, lapack_int ldbb, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zhbgvd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* bb, lapack_int ldbb, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_chbgvx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* bb, lapack_int ldbb, lapack_complex_float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_zhbgvx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* bb, lapack_int ldbb, lapack_complex_double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_chbtrd_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab, float* d, float* e, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* work ); lapack_int LAPACKE_zhbtrd_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab, double* d, double* e, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* work ); lapack_int LAPACKE_checon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, float anorm, float* rcond, lapack_complex_float* work ); lapack_int LAPACKE_zhecon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, double anorm, double* rcond, lapack_complex_double* work ); lapack_int LAPACKE_cheequb_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax, lapack_complex_float* work ); lapack_int LAPACKE_zheequb_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax, lapack_complex_double* work ); lapack_int LAPACKE_cheev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float* w, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zheev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* w, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_cheevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float* w, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zheevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* w, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_cheevr_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* isuppz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zheevr_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* isuppz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_cheevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_zheevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_chegst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhegst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chegv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* w, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zhegv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* w, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_chegvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float* w, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zhegvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double* w, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_chegvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_zhegvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_cherfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zherfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_cherfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const float* s, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zherfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const double* s, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chesv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zhesv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_chesvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zhesvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_chesvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhesvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chetrd_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, float* d, float* e, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zhetrd_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, double* d, double* e, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_chetrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zhetrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_chetri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work ); lapack_int LAPACKE_zhetri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work ); lapack_int LAPACKE_chetrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhetrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chfrk_work( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, float alpha, const lapack_complex_float* a, lapack_int lda, float beta, lapack_complex_float* c ); lapack_int LAPACKE_zhfrk_work( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, double alpha, const lapack_complex_double* a, lapack_int lda, double beta, lapack_complex_double* c ); lapack_int LAPACKE_shgeqz_work( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, float* h, lapack_int ldh, float* t, lapack_int ldt, float* alphar, float* alphai, float* beta, float* q, lapack_int ldq, float* z, lapack_int ldz, float* work, lapack_int lwork ); lapack_int LAPACKE_dhgeqz_work( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, double* h, lapack_int ldh, double* t, lapack_int ldt, double* alphar, double* alphai, double* beta, double* q, lapack_int ldq, double* z, lapack_int ldz, double* work, lapack_int lwork ); lapack_int LAPACKE_chgeqz_work( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* h, lapack_int ldh, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zhgeqz_work( int matrix_order, char job, char compq, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* h, lapack_int ldh, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_chpcon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, const lapack_int* ipiv, float anorm, float* rcond, lapack_complex_float* work ); lapack_int LAPACKE_zhpcon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, const lapack_int* ipiv, double anorm, double* rcond, lapack_complex_double* work ); lapack_int LAPACKE_chpev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhpev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chpevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zhpevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_chpevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* ap, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_zhpevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* ap, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_chpgst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_float* ap, const lapack_complex_float* bp ); lapack_int LAPACKE_zhpgst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, lapack_complex_double* ap, const lapack_complex_double* bp ); lapack_int LAPACKE_chpgv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, lapack_complex_float* bp, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhpgv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, lapack_complex_double* bp, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chpgvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_float* ap, lapack_complex_float* bp, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zhpgvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, lapack_complex_double* ap, lapack_complex_double* bp, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_chpgvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_float* ap, lapack_complex_float* bp, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_zhpgvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, lapack_complex_double* ap, lapack_complex_double* bp, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_chprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chpsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhpsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_chpsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* afp, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zhpsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* afp, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_chptrd_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, float* d, float* e, lapack_complex_float* tau ); lapack_int LAPACKE_zhptrd_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, double* d, double* e, lapack_complex_double* tau ); lapack_int LAPACKE_chptrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, lapack_int* ipiv ); lapack_int LAPACKE_zhptrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, lapack_int* ipiv ); lapack_int LAPACKE_chptri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* work ); lapack_int LAPACKE_zhptri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* work ); lapack_int LAPACKE_chptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zhptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_shsein_work( int matrix_order, char job, char eigsrc, char initv, lapack_logical* select, lapack_int n, const float* h, lapack_int ldh, float* wr, const float* wi, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, float* work, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_dhsein_work( int matrix_order, char job, char eigsrc, char initv, lapack_logical* select, lapack_int n, const double* h, lapack_int ldh, double* wr, const double* wi, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, double* work, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_chsein_work( int matrix_order, char job, char eigsrc, char initv, const lapack_logical* select, lapack_int n, const lapack_complex_float* h, lapack_int ldh, lapack_complex_float* w, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_complex_float* work, float* rwork, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_zhsein_work( int matrix_order, char job, char eigsrc, char initv, const lapack_logical* select, lapack_int n, const lapack_complex_double* h, lapack_int ldh, lapack_complex_double* w, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_complex_double* work, double* rwork, lapack_int* ifaill, lapack_int* ifailr ); lapack_int LAPACKE_shseqr_work( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, float* h, lapack_int ldh, float* wr, float* wi, float* z, lapack_int ldz, float* work, lapack_int lwork ); lapack_int LAPACKE_dhseqr_work( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, double* h, lapack_int ldh, double* wr, double* wi, double* z, lapack_int ldz, double* work, lapack_int lwork ); lapack_int LAPACKE_chseqr_work( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* h, lapack_int ldh, lapack_complex_float* w, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zhseqr_work( int matrix_order, char job, char compz, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* h, lapack_int ldh, lapack_complex_double* w, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_clacgv_work( lapack_int n, lapack_complex_float* x, lapack_int incx ); lapack_int LAPACKE_zlacgv_work( lapack_int n, lapack_complex_double* x, lapack_int incx ); lapack_int LAPACKE_slacn2_work( lapack_int n, float* v, float* x, lapack_int* isgn, float* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_dlacn2_work( lapack_int n, double* v, double* x, lapack_int* isgn, double* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_clacn2_work( lapack_int n, lapack_complex_float* v, lapack_complex_float* x, float* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_zlacn2_work( lapack_int n, lapack_complex_double* v, lapack_complex_double* x, double* est, lapack_int* kase, lapack_int* isave ); lapack_int LAPACKE_slacpy_work( int matrix_order, char uplo, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dlacpy_work( int matrix_order, char uplo, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_clacpy_work( int matrix_order, char uplo, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zlacpy_work( int matrix_order, char uplo, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_clacp2_work( int matrix_order, char uplo, lapack_int m, lapack_int n, const float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zlacp2_work( int matrix_order, char uplo, lapack_int m, lapack_int n, const double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_zlag2c_work( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_float* sa, lapack_int ldsa ); lapack_int LAPACKE_slag2d_work( int matrix_order, lapack_int m, lapack_int n, const float* sa, lapack_int ldsa, double* a, lapack_int lda ); lapack_int LAPACKE_dlag2s_work( int matrix_order, lapack_int m, lapack_int n, const double* a, lapack_int lda, float* sa, lapack_int ldsa ); lapack_int LAPACKE_clag2z_work( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* sa, lapack_int ldsa, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_slagge_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* d, float* a, lapack_int lda, lapack_int* iseed, float* work ); lapack_int LAPACKE_dlagge_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* d, double* a, lapack_int lda, lapack_int* iseed, double* work ); lapack_int LAPACKE_clagge_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float* d, lapack_complex_float* a, lapack_int lda, lapack_int* iseed, lapack_complex_float* work ); lapack_int LAPACKE_zlagge_work( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double* d, lapack_complex_double* a, lapack_int lda, lapack_int* iseed, lapack_complex_double* work ); lapack_int LAPACKE_claghe_work( int matrix_order, lapack_int n, lapack_int k, const float* d, lapack_complex_float* a, lapack_int lda, lapack_int* iseed, lapack_complex_float* work ); lapack_int LAPACKE_zlaghe_work( int matrix_order, lapack_int n, lapack_int k, const double* d, lapack_complex_double* a, lapack_int lda, lapack_int* iseed, lapack_complex_double* work ); lapack_int LAPACKE_slagsy_work( int matrix_order, lapack_int n, lapack_int k, const float* d, float* a, lapack_int lda, lapack_int* iseed, float* work ); lapack_int LAPACKE_dlagsy_work( int matrix_order, lapack_int n, lapack_int k, const double* d, double* a, lapack_int lda, lapack_int* iseed, double* work ); lapack_int LAPACKE_clagsy_work( int matrix_order, lapack_int n, lapack_int k, const float* d, lapack_complex_float* a, lapack_int lda, lapack_int* iseed, lapack_complex_float* work ); lapack_int LAPACKE_zlagsy_work( int matrix_order, lapack_int n, lapack_int k, const double* d, lapack_complex_double* a, lapack_int lda, lapack_int* iseed, lapack_complex_double* work ); lapack_int LAPACKE_slapmr_work( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, float* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_dlapmr_work( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, double* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_clapmr_work( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, lapack_complex_float* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_zlapmr_work( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, lapack_complex_double* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_slartgp_work( float f, float g, float* cs, float* sn, float* r ); lapack_int LAPACKE_dlartgp_work( double f, double g, double* cs, double* sn, double* r ); lapack_int LAPACKE_slartgs_work( float x, float y, float sigma, float* cs, float* sn ); lapack_int LAPACKE_dlartgs_work( double x, double y, double sigma, double* cs, double* sn ); float LAPACKE_slapy2_work( float x, float y ); double LAPACKE_dlapy2_work( double x, double y ); float LAPACKE_slapy3_work( float x, float y, float z ); double LAPACKE_dlapy3_work( double x, double y, double z ); float LAPACKE_slamch_work( char cmach ); double LAPACKE_dlamch_work( char cmach ); float LAPACKE_slange_work( int matrix_order, char norm, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* work ); double LAPACKE_dlange_work( int matrix_order, char norm, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* work ); float LAPACKE_clange_work( int matrix_order, char norm, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* work ); double LAPACKE_zlange_work( int matrix_order, char norm, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* work ); float LAPACKE_clanhe_work( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* work ); double LAPACKE_zlanhe_work( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* work ); float LAPACKE_slansy_work( int matrix_order, char norm, char uplo, lapack_int n, const float* a, lapack_int lda, float* work ); double LAPACKE_dlansy_work( int matrix_order, char norm, char uplo, lapack_int n, const double* a, lapack_int lda, double* work ); float LAPACKE_clansy_work( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* work ); double LAPACKE_zlansy_work( int matrix_order, char norm, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* work ); float LAPACKE_slantr_work( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const float* a, lapack_int lda, float* work ); double LAPACKE_dlantr_work( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const double* a, lapack_int lda, double* work ); float LAPACKE_clantr_work( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* work ); double LAPACKE_zlantr_work( int matrix_order, char norm, char uplo, char diag, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* work ); lapack_int LAPACKE_slarfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* c, lapack_int ldc, float* work, lapack_int ldwork ); lapack_int LAPACKE_dlarfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* c, lapack_int ldc, double* work, lapack_int ldwork ); lapack_int LAPACKE_clarfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int ldwork ); lapack_int LAPACKE_zlarfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int ldwork ); lapack_int LAPACKE_slarfg_work( lapack_int n, float* alpha, float* x, lapack_int incx, float* tau ); lapack_int LAPACKE_dlarfg_work( lapack_int n, double* alpha, double* x, lapack_int incx, double* tau ); lapack_int LAPACKE_clarfg_work( lapack_int n, lapack_complex_float* alpha, lapack_complex_float* x, lapack_int incx, lapack_complex_float* tau ); lapack_int LAPACKE_zlarfg_work( lapack_int n, lapack_complex_double* alpha, lapack_complex_double* x, lapack_int incx, lapack_complex_double* tau ); lapack_int LAPACKE_slarft_work( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const float* v, lapack_int ldv, const float* tau, float* t, lapack_int ldt ); lapack_int LAPACKE_dlarft_work( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const double* v, lapack_int ldv, const double* tau, double* t, lapack_int ldt ); lapack_int LAPACKE_clarft_work( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* tau, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zlarft_work( int matrix_order, char direct, char storev, lapack_int n, lapack_int k, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* tau, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_slarfx_work( int matrix_order, char side, lapack_int m, lapack_int n, const float* v, float tau, float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_dlarfx_work( int matrix_order, char side, lapack_int m, lapack_int n, const double* v, double tau, double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_clarfx_work( int matrix_order, char side, lapack_int m, lapack_int n, const lapack_complex_float* v, lapack_complex_float tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work ); lapack_int LAPACKE_zlarfx_work( int matrix_order, char side, lapack_int m, lapack_int n, const lapack_complex_double* v, lapack_complex_double tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work ); lapack_int LAPACKE_slarnv_work( lapack_int idist, lapack_int* iseed, lapack_int n, float* x ); lapack_int LAPACKE_dlarnv_work( lapack_int idist, lapack_int* iseed, lapack_int n, double* x ); lapack_int LAPACKE_clarnv_work( lapack_int idist, lapack_int* iseed, lapack_int n, lapack_complex_float* x ); lapack_int LAPACKE_zlarnv_work( lapack_int idist, lapack_int* iseed, lapack_int n, lapack_complex_double* x ); lapack_int LAPACKE_slaset_work( int matrix_order, char uplo, lapack_int m, lapack_int n, float alpha, float beta, float* a, lapack_int lda ); lapack_int LAPACKE_dlaset_work( int matrix_order, char uplo, lapack_int m, lapack_int n, double alpha, double beta, double* a, lapack_int lda ); lapack_int LAPACKE_claset_work( int matrix_order, char uplo, lapack_int m, lapack_int n, lapack_complex_float alpha, lapack_complex_float beta, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zlaset_work( int matrix_order, char uplo, lapack_int m, lapack_int n, lapack_complex_double alpha, lapack_complex_double beta, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_slasrt_work( char id, lapack_int n, float* d ); lapack_int LAPACKE_dlasrt_work( char id, lapack_int n, double* d ); lapack_int LAPACKE_slaswp_work( int matrix_order, lapack_int n, float* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_dlaswp_work( int matrix_order, lapack_int n, double* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_claswp_work( int matrix_order, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_zlaswp_work( int matrix_order, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int k1, lapack_int k2, const lapack_int* ipiv, lapack_int incx ); lapack_int LAPACKE_slatms_work( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, float* d, lapack_int mode, float cond, float dmax, lapack_int kl, lapack_int ku, char pack, float* a, lapack_int lda, float* work ); lapack_int LAPACKE_dlatms_work( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, double* d, lapack_int mode, double cond, double dmax, lapack_int kl, lapack_int ku, char pack, double* a, lapack_int lda, double* work ); lapack_int LAPACKE_clatms_work( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, float* d, lapack_int mode, float cond, float dmax, lapack_int kl, lapack_int ku, char pack, lapack_complex_float* a, lapack_int lda, lapack_complex_float* work ); lapack_int LAPACKE_zlatms_work( int matrix_order, lapack_int m, lapack_int n, char dist, lapack_int* iseed, char sym, double* d, lapack_int mode, double cond, double dmax, lapack_int kl, lapack_int ku, char pack, lapack_complex_double* a, lapack_int lda, lapack_complex_double* work ); lapack_int LAPACKE_slauum_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dlauum_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_clauum_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zlauum_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_sopgtr_work( int matrix_order, char uplo, lapack_int n, const float* ap, const float* tau, float* q, lapack_int ldq, float* work ); lapack_int LAPACKE_dopgtr_work( int matrix_order, char uplo, lapack_int n, const double* ap, const double* tau, double* q, lapack_int ldq, double* work ); lapack_int LAPACKE_sopmtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const float* ap, const float* tau, float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_dopmtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const double* ap, const double* tau, double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_sorgbr_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorgbr_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sorghr_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorghr_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sorglq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorglq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sorgql_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorgql_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sorgqr_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorgqr_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sorgrq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorgrq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sorgtr_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dorgtr_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_sormbr_work( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormbr_work( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormhr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormhr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormlq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormlq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormql_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormql_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormqr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormqr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormrq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormrq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormrz_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormrz_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_sormtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const float* a, lapack_int lda, const float* tau, float* c, lapack_int ldc, float* work, lapack_int lwork ); lapack_int LAPACKE_dormtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const double* a, lapack_int lda, const double* tau, double* c, lapack_int ldc, double* work, lapack_int lwork ); lapack_int LAPACKE_spbcon_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dpbcon_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cpbcon_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab, float anorm, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zpbcon_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab, double anorm, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spbequ_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab, float* s, float* scond, float* amax ); lapack_int LAPACKE_dpbequ_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab, double* s, double* scond, double* amax ); lapack_int LAPACKE_cpbequ_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab, float* s, float* scond, float* amax ); lapack_int LAPACKE_zpbequ_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab, double* s, double* scond, double* amax ); lapack_int LAPACKE_spbrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, const float* afb, lapack_int ldafb, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dpbrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, const double* afb, lapack_int ldafb, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cpbrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* afb, lapack_int ldafb, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zpbrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* afb, lapack_int ldafb, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spbstf_work( int matrix_order, char uplo, lapack_int n, lapack_int kb, float* bb, lapack_int ldbb ); lapack_int LAPACKE_dpbstf_work( int matrix_order, char uplo, lapack_int n, lapack_int kb, double* bb, lapack_int ldbb ); lapack_int LAPACKE_cpbstf_work( int matrix_order, char uplo, lapack_int n, lapack_int kb, lapack_complex_float* bb, lapack_int ldbb ); lapack_int LAPACKE_zpbstf_work( int matrix_order, char uplo, lapack_int n, lapack_int kb, lapack_complex_double* bb, lapack_int ldbb ); lapack_int LAPACKE_spbsv_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, float* ab, lapack_int ldab, float* b, lapack_int ldb ); lapack_int LAPACKE_dpbsv_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, double* ab, lapack_int ldab, double* b, lapack_int ldb ); lapack_int LAPACKE_cpbsv_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpbsv_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spbsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, float* ab, lapack_int ldab, float* afb, lapack_int ldafb, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dpbsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, double* ab, lapack_int ldab, double* afb, lapack_int ldafb, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cpbsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* afb, lapack_int ldafb, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zpbsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* afb, lapack_int ldafb, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spbtrf_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab ); lapack_int LAPACKE_dpbtrf_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab ); lapack_int LAPACKE_cpbtrf_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_complex_float* ab, lapack_int ldab ); lapack_int LAPACKE_zpbtrf_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_complex_double* ab, lapack_int ldab ); lapack_int LAPACKE_spbtrs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, float* b, lapack_int ldb ); lapack_int LAPACKE_dpbtrs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, double* b, lapack_int ldb ); lapack_int LAPACKE_cpbtrs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpbtrs_work( int matrix_order, char uplo, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spftrf_work( int matrix_order, char transr, char uplo, lapack_int n, float* a ); lapack_int LAPACKE_dpftrf_work( int matrix_order, char transr, char uplo, lapack_int n, double* a ); lapack_int LAPACKE_cpftrf_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_float* a ); lapack_int LAPACKE_zpftrf_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_double* a ); lapack_int LAPACKE_spftri_work( int matrix_order, char transr, char uplo, lapack_int n, float* a ); lapack_int LAPACKE_dpftri_work( int matrix_order, char transr, char uplo, lapack_int n, double* a ); lapack_int LAPACKE_cpftri_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_float* a ); lapack_int LAPACKE_zpftri_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_complex_double* a ); lapack_int LAPACKE_spftrs_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const float* a, float* b, lapack_int ldb ); lapack_int LAPACKE_dpftrs_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const double* a, double* b, lapack_int ldb ); lapack_int LAPACKE_cpftrs_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpftrs_work( int matrix_order, char transr, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spocon_work( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dpocon_work( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cpocon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float anorm, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zpocon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double anorm, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spoequ_work( int matrix_order, lapack_int n, const float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_dpoequ_work( int matrix_order, lapack_int n, const double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_cpoequ_work( int matrix_order, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_zpoequ_work( int matrix_order, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_spoequb_work( int matrix_order, lapack_int n, const float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_dpoequb_work( int matrix_order, lapack_int n, const double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_cpoequb_work( int matrix_order, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax ); lapack_int LAPACKE_zpoequb_work( int matrix_order, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax ); lapack_int LAPACKE_sporfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dporfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cporfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zporfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sporfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const float* s, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dporfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const double* s, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_cporfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const float* s, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zporfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const double* s, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sposv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dposv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_cposv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zposv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_dsposv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* b, lapack_int ldb, double* x, lapack_int ldx, double* work, float* swork, lapack_int* iter ); lapack_int LAPACKE_zcposv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, lapack_complex_double* work, lapack_complex_float* swork, double* rwork, lapack_int* iter ); lapack_int LAPACKE_sposvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dposvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cposvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zposvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sposvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dposvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_cposvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zposvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spotrf_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dpotrf_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_cpotrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zpotrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_spotri_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dpotri_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_cpotri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zpotri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_spotrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dpotrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_cpotrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpotrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sppcon_work( int matrix_order, char uplo, lapack_int n, const float* ap, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dppcon_work( int matrix_order, char uplo, lapack_int n, const double* ap, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cppcon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, float anorm, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zppcon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, double anorm, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sppequ_work( int matrix_order, char uplo, lapack_int n, const float* ap, float* s, float* scond, float* amax ); lapack_int LAPACKE_dppequ_work( int matrix_order, char uplo, lapack_int n, const double* ap, double* s, double* scond, double* amax ); lapack_int LAPACKE_cppequ_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, float* s, float* scond, float* amax ); lapack_int LAPACKE_zppequ_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, double* s, double* scond, double* amax ); lapack_int LAPACKE_spprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, const float* afp, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dpprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, const double* afp, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cpprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zpprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sppsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* ap, float* b, lapack_int ldb ); lapack_int LAPACKE_dppsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* ap, double* b, lapack_int ldb ); lapack_int LAPACKE_cppsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zppsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sppsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* ap, float* afp, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dppsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* ap, double* afp, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cppsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_complex_float* afp, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zppsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_complex_double* afp, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spptrf_work( int matrix_order, char uplo, lapack_int n, float* ap ); lapack_int LAPACKE_dpptrf_work( int matrix_order, char uplo, lapack_int n, double* ap ); lapack_int LAPACKE_cpptrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap ); lapack_int LAPACKE_zpptrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap ); lapack_int LAPACKE_spptri_work( int matrix_order, char uplo, lapack_int n, float* ap ); lapack_int LAPACKE_dpptri_work( int matrix_order, char uplo, lapack_int n, double* ap ); lapack_int LAPACKE_cpptri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap ); lapack_int LAPACKE_zpptri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap ); lapack_int LAPACKE_spptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, float* b, lapack_int ldb ); lapack_int LAPACKE_dpptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, double* b, lapack_int ldb ); lapack_int LAPACKE_cpptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_spstrf_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, lapack_int* piv, lapack_int* rank, float tol, float* work ); lapack_int LAPACKE_dpstrf_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, lapack_int* piv, lapack_int* rank, double tol, double* work ); lapack_int LAPACKE_cpstrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* piv, lapack_int* rank, float tol, float* work ); lapack_int LAPACKE_zpstrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* piv, lapack_int* rank, double tol, double* work ); lapack_int LAPACKE_sptcon_work( lapack_int n, const float* d, const float* e, float anorm, float* rcond, float* work ); lapack_int LAPACKE_dptcon_work( lapack_int n, const double* d, const double* e, double anorm, double* rcond, double* work ); lapack_int LAPACKE_cptcon_work( lapack_int n, const float* d, const lapack_complex_float* e, float anorm, float* rcond, float* work ); lapack_int LAPACKE_zptcon_work( lapack_int n, const double* d, const lapack_complex_double* e, double anorm, double* rcond, double* work ); lapack_int LAPACKE_spteqr_work( int matrix_order, char compz, lapack_int n, float* d, float* e, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dpteqr_work( int matrix_order, char compz, lapack_int n, double* d, double* e, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_cpteqr_work( int matrix_order, char compz, lapack_int n, float* d, float* e, lapack_complex_float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_zpteqr_work( int matrix_order, char compz, lapack_int n, double* d, double* e, lapack_complex_double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_sptrfs_work( int matrix_order, lapack_int n, lapack_int nrhs, const float* d, const float* e, const float* df, const float* ef, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work ); lapack_int LAPACKE_dptrfs_work( int matrix_order, lapack_int n, lapack_int nrhs, const double* d, const double* e, const double* df, const double* ef, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work ); lapack_int LAPACKE_cptrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* d, const lapack_complex_float* e, const float* df, const lapack_complex_float* ef, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zptrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* d, const lapack_complex_double* e, const double* df, const lapack_complex_double* ef, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sptsv_work( int matrix_order, lapack_int n, lapack_int nrhs, float* d, float* e, float* b, lapack_int ldb ); lapack_int LAPACKE_dptsv_work( int matrix_order, lapack_int n, lapack_int nrhs, double* d, double* e, double* b, lapack_int ldb ); lapack_int LAPACKE_cptsv_work( int matrix_order, lapack_int n, lapack_int nrhs, float* d, lapack_complex_float* e, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zptsv_work( int matrix_order, lapack_int n, lapack_int nrhs, double* d, lapack_complex_double* e, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sptsvx_work( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const float* d, const float* e, float* df, float* ef, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work ); lapack_int LAPACKE_dptsvx_work( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const double* d, const double* e, double* df, double* ef, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work ); lapack_int LAPACKE_cptsvx_work( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const float* d, const lapack_complex_float* e, float* df, lapack_complex_float* ef, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zptsvx_work( int matrix_order, char fact, lapack_int n, lapack_int nrhs, const double* d, const lapack_complex_double* e, double* df, lapack_complex_double* ef, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_spttrf_work( lapack_int n, float* d, float* e ); lapack_int LAPACKE_dpttrf_work( lapack_int n, double* d, double* e ); lapack_int LAPACKE_cpttrf_work( lapack_int n, float* d, lapack_complex_float* e ); lapack_int LAPACKE_zpttrf_work( lapack_int n, double* d, lapack_complex_double* e ); lapack_int LAPACKE_spttrs_work( int matrix_order, lapack_int n, lapack_int nrhs, const float* d, const float* e, float* b, lapack_int ldb ); lapack_int LAPACKE_dpttrs_work( int matrix_order, lapack_int n, lapack_int nrhs, const double* d, const double* e, double* b, lapack_int ldb ); lapack_int LAPACKE_cpttrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* d, const lapack_complex_float* e, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zpttrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* d, const lapack_complex_double* e, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_ssbev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* w, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dsbev_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* w, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_ssbevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* w, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dsbevd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* w, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ssbevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dsbevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_ssbgst_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, const float* bb, lapack_int ldbb, float* x, lapack_int ldx, float* work ); lapack_int LAPACKE_dsbgst_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, const double* bb, lapack_int ldbb, double* x, lapack_int ldx, double* work ); lapack_int LAPACKE_ssbgv_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, float* bb, lapack_int ldbb, float* w, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dsbgv_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, double* bb, lapack_int ldbb, double* w, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_ssbgvd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, float* bb, lapack_int ldbb, float* w, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dsbgvd_work( int matrix_order, char jobz, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, double* bb, lapack_int ldbb, double* w, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ssbgvx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, float* ab, lapack_int ldab, float* bb, lapack_int ldbb, float* q, lapack_int ldq, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dsbgvx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, lapack_int ka, lapack_int kb, double* ab, lapack_int ldab, double* bb, lapack_int ldbb, double* q, lapack_int ldq, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_ssbtrd_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, float* ab, lapack_int ldab, float* d, float* e, float* q, lapack_int ldq, float* work ); lapack_int LAPACKE_dsbtrd_work( int matrix_order, char vect, char uplo, lapack_int n, lapack_int kd, double* ab, lapack_int ldab, double* d, double* e, double* q, lapack_int ldq, double* work ); lapack_int LAPACKE_ssfrk_work( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, float alpha, const float* a, lapack_int lda, float beta, float* c ); lapack_int LAPACKE_dsfrk_work( int matrix_order, char transr, char uplo, char trans, lapack_int n, lapack_int k, double alpha, const double* a, lapack_int lda, double beta, double* c ); lapack_int LAPACKE_sspcon_work( int matrix_order, char uplo, lapack_int n, const float* ap, const lapack_int* ipiv, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dspcon_work( int matrix_order, char uplo, lapack_int n, const double* ap, const lapack_int* ipiv, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_cspcon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, const lapack_int* ipiv, float anorm, float* rcond, lapack_complex_float* work ); lapack_int LAPACKE_zspcon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, const lapack_int* ipiv, double anorm, double* rcond, lapack_complex_double* work ); lapack_int LAPACKE_sspev_work( int matrix_order, char jobz, char uplo, lapack_int n, float* ap, float* w, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dspev_work( int matrix_order, char jobz, char uplo, lapack_int n, double* ap, double* w, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_sspevd_work( int matrix_order, char jobz, char uplo, lapack_int n, float* ap, float* w, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dspevd_work( int matrix_order, char jobz, char uplo, lapack_int n, double* ap, double* w, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_sspevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, float* ap, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dspevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, double* ap, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_sspgst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, float* ap, const float* bp ); lapack_int LAPACKE_dspgst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, double* ap, const double* bp ); lapack_int LAPACKE_sspgv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* ap, float* bp, float* w, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dspgv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* ap, double* bp, double* w, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_sspgvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* ap, float* bp, float* w, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dspgvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* ap, double* bp, double* w, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_sspgvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, float* ap, float* bp, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dspgvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, double* ap, double* bp, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_ssprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, const float* afp, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dsprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, const double* afp, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_csprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zsprfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_sspsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* ap, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dspsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* ap, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_cspsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* ap, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zspsv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* ap, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sspsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const float* ap, float* afp, lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dspsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const double* ap, double* afp, lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_cspsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* afp, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zspsvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* afp, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_ssptrd_work( int matrix_order, char uplo, lapack_int n, float* ap, float* d, float* e, float* tau ); lapack_int LAPACKE_dsptrd_work( int matrix_order, char uplo, lapack_int n, double* ap, double* d, double* e, double* tau ); lapack_int LAPACKE_ssptrf_work( int matrix_order, char uplo, lapack_int n, float* ap, lapack_int* ipiv ); lapack_int LAPACKE_dsptrf_work( int matrix_order, char uplo, lapack_int n, double* ap, lapack_int* ipiv ); lapack_int LAPACKE_csptrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, lapack_int* ipiv ); lapack_int LAPACKE_zsptrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, lapack_int* ipiv ); lapack_int LAPACKE_ssptri_work( int matrix_order, char uplo, lapack_int n, float* ap, const lapack_int* ipiv, float* work ); lapack_int LAPACKE_dsptri_work( int matrix_order, char uplo, lapack_int n, double* ap, const lapack_int* ipiv, double* work ); lapack_int LAPACKE_csptri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* work ); lapack_int LAPACKE_zsptri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* work ); lapack_int LAPACKE_ssptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* ap, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dsptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* ap, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_csptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zsptrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sstebz_work( char range, char order, lapack_int n, float vl, float vu, lapack_int il, lapack_int iu, float abstol, const float* d, const float* e, lapack_int* m, lapack_int* nsplit, float* w, lapack_int* iblock, lapack_int* isplit, float* work, lapack_int* iwork ); lapack_int LAPACKE_dstebz_work( char range, char order, lapack_int n, double vl, double vu, lapack_int il, lapack_int iu, double abstol, const double* d, const double* e, lapack_int* m, lapack_int* nsplit, double* w, lapack_int* iblock, lapack_int* isplit, double* work, lapack_int* iwork ); lapack_int LAPACKE_sstedc_work( int matrix_order, char compz, lapack_int n, float* d, float* e, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dstedc_work( int matrix_order, char compz, lapack_int n, double* d, double* e, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_cstedc_work( int matrix_order, char compz, lapack_int n, float* d, float* e, lapack_complex_float* z, lapack_int ldz, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zstedc_work( int matrix_order, char compz, lapack_int n, double* d, double* e, lapack_complex_double* z, lapack_int ldz, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_sstegr_work( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dstegr_work( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_cstegr_work( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int* isuppz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zstegr_work( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int* isuppz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_sstein_work( int matrix_order, lapack_int n, const float* d, const float* e, lapack_int m, const float* w, const lapack_int* iblock, const lapack_int* isplit, float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifailv ); lapack_int LAPACKE_dstein_work( int matrix_order, lapack_int n, const double* d, const double* e, lapack_int m, const double* w, const lapack_int* iblock, const lapack_int* isplit, double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifailv ); lapack_int LAPACKE_cstein_work( int matrix_order, lapack_int n, const float* d, const float* e, lapack_int m, const float* w, const lapack_int* iblock, const lapack_int* isplit, lapack_complex_float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifailv ); lapack_int LAPACKE_zstein_work( int matrix_order, lapack_int n, const double* d, const double* e, lapack_int m, const double* w, const lapack_int* iblock, const lapack_int* isplit, lapack_complex_double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifailv ); lapack_int LAPACKE_sstemr_work( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dstemr_work( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_cstemr_work( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, lapack_int* m, float* w, lapack_complex_float* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_zstemr_work( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, lapack_int* m, double* w, lapack_complex_double* z, lapack_int ldz, lapack_int nzc, lapack_int* isuppz, lapack_logical* tryrac, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ssteqr_work( int matrix_order, char compz, lapack_int n, float* d, float* e, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dsteqr_work( int matrix_order, char compz, lapack_int n, double* d, double* e, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_csteqr_work( int matrix_order, char compz, lapack_int n, float* d, float* e, lapack_complex_float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_zsteqr_work( int matrix_order, char compz, lapack_int n, double* d, double* e, lapack_complex_double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_ssterf_work( lapack_int n, float* d, float* e ); lapack_int LAPACKE_dsterf_work( lapack_int n, double* d, double* e ); lapack_int LAPACKE_sstev_work( int matrix_order, char jobz, lapack_int n, float* d, float* e, float* z, lapack_int ldz, float* work ); lapack_int LAPACKE_dstev_work( int matrix_order, char jobz, lapack_int n, double* d, double* e, double* z, lapack_int ldz, double* work ); lapack_int LAPACKE_sstevd_work( int matrix_order, char jobz, lapack_int n, float* d, float* e, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dstevd_work( int matrix_order, char jobz, lapack_int n, double* d, double* e, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_sstevr_work( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dstevr_work( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_sstevx_work( int matrix_order, char jobz, char range, lapack_int n, float* d, float* e, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dstevx_work( int matrix_order, char jobz, char range, lapack_int n, double* d, double* e, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_ssycon_work( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, const lapack_int* ipiv, float anorm, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dsycon_work( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, const lapack_int* ipiv, double anorm, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_csycon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, float anorm, float* rcond, lapack_complex_float* work ); lapack_int LAPACKE_zsycon_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, double anorm, double* rcond, lapack_complex_double* work ); lapack_int LAPACKE_ssyequb_work( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, float* s, float* scond, float* amax, float* work ); lapack_int LAPACKE_dsyequb_work( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, double* s, double* scond, double* amax, double* work ); lapack_int LAPACKE_csyequb_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* s, float* scond, float* amax, lapack_complex_float* work ); lapack_int LAPACKE_zsyequb_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* s, double* scond, double* amax, lapack_complex_double* work ); lapack_int LAPACKE_ssyev_work( int matrix_order, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* w, float* work, lapack_int lwork ); lapack_int LAPACKE_dsyev_work( int matrix_order, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* w, double* work, lapack_int lwork ); lapack_int LAPACKE_ssyevd_work( int matrix_order, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* w, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dsyevd_work( int matrix_order, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* w, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ssyevr_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, lapack_int* isuppz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dsyevr_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, lapack_int* isuppz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ssyevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, float* a, lapack_int lda, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dsyevx_work( int matrix_order, char jobz, char range, char uplo, lapack_int n, double* a, lapack_int lda, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_ssygst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, float* a, lapack_int lda, const float* b, lapack_int ldb ); lapack_int LAPACKE_dsygst_work( int matrix_order, lapack_int itype, char uplo, lapack_int n, double* a, lapack_int lda, const double* b, lapack_int ldb ); lapack_int LAPACKE_ssygv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* w, float* work, lapack_int lwork ); lapack_int LAPACKE_dsygv_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* w, double* work, lapack_int lwork ); lapack_int LAPACKE_ssygvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* w, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dsygvd_work( int matrix_order, lapack_int itype, char jobz, char uplo, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* w, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ssygvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float vl, float vu, lapack_int il, lapack_int iu, float abstol, lapack_int* m, float* w, float* z, lapack_int ldz, float* work, lapack_int lwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_dsygvx_work( int matrix_order, lapack_int itype, char jobz, char range, char uplo, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double vl, double vu, lapack_int il, lapack_int iu, double abstol, lapack_int* m, double* w, double* z, lapack_int ldz, double* work, lapack_int lwork, lapack_int* iwork, lapack_int* ifail ); lapack_int LAPACKE_ssyrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dsyrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_csyrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zsyrfs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_ssyrfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* af, lapack_int ldaf, const lapack_int* ipiv, const float* s, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dsyrfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* af, lapack_int ldaf, const lapack_int* ipiv, const double* s, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_csyrfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* af, lapack_int ldaf, const lapack_int* ipiv, const float* s, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zsyrfsx_work( int matrix_order, char uplo, char equed, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* af, lapack_int ldaf, const lapack_int* ipiv, const double* s, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_ssysv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb, float* work, lapack_int lwork ); lapack_int LAPACKE_dsysv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb, double* work, lapack_int lwork ); lapack_int LAPACKE_csysv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zsysv_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_ssysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb, float* work, lapack_int lwork ); lapack_int LAPACKE_dsysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb, double* work, lapack_int lwork ); lapack_int LAPACKE_csysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zsysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_ssysvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, const float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dsysvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, const double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_csysvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, lapack_int lwork, float* rwork ); lapack_int LAPACKE_zsysvx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, lapack_int lwork, double* rwork ); lapack_int LAPACKE_ssysvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* s, float* b, lapack_int ldb, float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, float* work, lapack_int* iwork ); lapack_int LAPACKE_dsysvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* s, double* b, lapack_int ldb, double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, double* work, lapack_int* iwork ); lapack_int LAPACKE_csysvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_complex_float* af, lapack_int ldaf, lapack_int* ipiv, char* equed, float* s, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* x, lapack_int ldx, float* rcond, float* rpvgrw, float* berr, lapack_int n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int nparams, float* params, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_zsysvxx_work( int matrix_order, char fact, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_complex_double* af, lapack_int ldaf, lapack_int* ipiv, char* equed, double* s, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* x, lapack_int ldx, double* rcond, double* rpvgrw, double* berr, lapack_int n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int nparams, double* params, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_ssytrd_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, float* d, float* e, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dsytrd_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, double* d, double* e, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_ssytrf_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, lapack_int* ipiv, float* work, lapack_int lwork ); lapack_int LAPACKE_dsytrf_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, lapack_int* ipiv, double* work, lapack_int lwork ); lapack_int LAPACKE_csytrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zsytrf_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_ssytri_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv, float* work ); lapack_int LAPACKE_dsytri_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv, double* work ); lapack_int LAPACKE_csytri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work ); lapack_int LAPACKE_zsytri_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work ); lapack_int LAPACKE_ssytrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dsytrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_csytrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zsytrs_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stbcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dtbcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_ctbcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztbcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_stbrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, const float* b, lapack_int ldb, const float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dtbrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, const double* b, lapack_int ldb, const double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_ctbrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztbrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_stbtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const float* ab, lapack_int ldab, float* b, lapack_int ldb ); lapack_int LAPACKE_dtbtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const double* ab, lapack_int ldab, double* b, lapack_int ldb ); lapack_int LAPACKE_ctbtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_float* ab, lapack_int ldab, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztbtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int kd, lapack_int nrhs, const lapack_complex_double* ab, lapack_int ldab, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stfsm_work( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, float alpha, const float* a, float* b, lapack_int ldb ); lapack_int LAPACKE_dtfsm_work( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, double alpha, const double* a, double* b, lapack_int ldb ); lapack_int LAPACKE_ctfsm_work( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, lapack_complex_float alpha, const lapack_complex_float* a, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztfsm_work( int matrix_order, char transr, char side, char uplo, char trans, char diag, lapack_int m, lapack_int n, lapack_complex_double alpha, const lapack_complex_double* a, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stftri_work( int matrix_order, char transr, char uplo, char diag, lapack_int n, float* a ); lapack_int LAPACKE_dtftri_work( int matrix_order, char transr, char uplo, char diag, lapack_int n, double* a ); lapack_int LAPACKE_ctftri_work( int matrix_order, char transr, char uplo, char diag, lapack_int n, lapack_complex_float* a ); lapack_int LAPACKE_ztftri_work( int matrix_order, char transr, char uplo, char diag, lapack_int n, lapack_complex_double* a ); lapack_int LAPACKE_stfttp_work( int matrix_order, char transr, char uplo, lapack_int n, const float* arf, float* ap ); lapack_int LAPACKE_dtfttp_work( int matrix_order, char transr, char uplo, lapack_int n, const double* arf, double* ap ); lapack_int LAPACKE_ctfttp_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* arf, lapack_complex_float* ap ); lapack_int LAPACKE_ztfttp_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* arf, lapack_complex_double* ap ); lapack_int LAPACKE_stfttr_work( int matrix_order, char transr, char uplo, lapack_int n, const float* arf, float* a, lapack_int lda ); lapack_int LAPACKE_dtfttr_work( int matrix_order, char transr, char uplo, lapack_int n, const double* arf, double* a, lapack_int lda ); lapack_int LAPACKE_ctfttr_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* arf, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_ztfttr_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* arf, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_stgevc_work( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const float* s, lapack_int lds, const float* p, lapack_int ldp, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, float* work ); lapack_int LAPACKE_dtgevc_work( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const double* s, lapack_int lds, const double* p, lapack_int ldp, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, double* work ); lapack_int LAPACKE_ctgevc_work( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_float* s, lapack_int lds, const lapack_complex_float* p, lapack_int ldp, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztgevc_work( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_double* s, lapack_int lds, const lapack_complex_double* p, lapack_int ldp, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_stgexc_work( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* q, lapack_int ldq, float* z, lapack_int ldz, lapack_int* ifst, lapack_int* ilst, float* work, lapack_int lwork ); lapack_int LAPACKE_dtgexc_work( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* q, lapack_int ldq, double* z, lapack_int ldz, lapack_int* ifst, lapack_int* ilst, double* work, lapack_int lwork ); lapack_int LAPACKE_ctgexc_work( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_ztgexc_work( int matrix_order, lapack_logical wantq, lapack_logical wantz, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_stgsen_work( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, float* a, lapack_int lda, float* b, lapack_int ldb, float* alphar, float* alphai, float* beta, float* q, lapack_int ldq, float* z, lapack_int ldz, lapack_int* m, float* pl, float* pr, float* dif, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dtgsen_work( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, double* a, lapack_int lda, double* b, lapack_int ldb, double* alphar, double* alphai, double* beta, double* q, lapack_int ldq, double* z, lapack_int ldz, lapack_int* m, double* pl, double* pr, double* dif, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ctgsen_work( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* z, lapack_int ldz, lapack_int* m, float* pl, float* pr, float* dif, lapack_complex_float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ztgsen_work( int matrix_order, lapack_int ijob, lapack_logical wantq, lapack_logical wantz, const lapack_logical* select, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* z, lapack_int ldz, lapack_int* m, double* pl, double* pr, double* dif, lapack_complex_double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_stgsja_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, float* a, lapack_int lda, float* b, lapack_int ldb, float tola, float tolb, float* alpha, float* beta, float* u, lapack_int ldu, float* v, lapack_int ldv, float* q, lapack_int ldq, float* work, lapack_int* ncycle ); lapack_int LAPACKE_dtgsja_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, double* a, lapack_int lda, double* b, lapack_int ldb, double tola, double tolb, double* alpha, double* beta, double* u, lapack_int ldu, double* v, lapack_int ldv, double* q, lapack_int ldq, double* work, lapack_int* ncycle ); lapack_int LAPACKE_ctgsja_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, float tola, float tolb, float* alpha, float* beta, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* v, lapack_int ldv, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* work, lapack_int* ncycle ); lapack_int LAPACKE_ztgsja_work( int matrix_order, char jobu, char jobv, char jobq, lapack_int m, lapack_int p, lapack_int n, lapack_int k, lapack_int l, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, double tola, double tolb, double* alpha, double* beta, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* v, lapack_int ldv, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* work, lapack_int* ncycle ); lapack_int LAPACKE_stgsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const float* a, lapack_int lda, const float* b, lapack_int ldb, const float* vl, lapack_int ldvl, const float* vr, lapack_int ldvr, float* s, float* dif, lapack_int mm, lapack_int* m, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dtgsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const double* a, lapack_int lda, const double* b, lapack_int ldb, const double* vl, lapack_int ldvl, const double* vr, lapack_int ldvr, double* s, double* dif, lapack_int mm, lapack_int* m, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_ctgsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* vl, lapack_int ldvl, const lapack_complex_float* vr, lapack_int ldvr, float* s, float* dif, lapack_int mm, lapack_int* m, lapack_complex_float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_ztgsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* vl, lapack_int ldvl, const lapack_complex_double* vr, lapack_int ldvr, double* s, double* dif, lapack_int mm, lapack_int* m, lapack_complex_double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_stgsyl_work( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const float* a, lapack_int lda, const float* b, lapack_int ldb, float* c, lapack_int ldc, const float* d, lapack_int ldd, const float* e, lapack_int lde, float* f, lapack_int ldf, float* scale, float* dif, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dtgsyl_work( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const double* a, lapack_int lda, const double* b, lapack_int ldb, double* c, lapack_int ldc, const double* d, lapack_int ldd, const double* e, lapack_int lde, double* f, lapack_int ldf, double* scale, double* dif, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_ctgsyl_work( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* c, lapack_int ldc, const lapack_complex_float* d, lapack_int ldd, const lapack_complex_float* e, lapack_int lde, lapack_complex_float* f, lapack_int ldf, float* scale, float* dif, lapack_complex_float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_ztgsyl_work( int matrix_order, char trans, lapack_int ijob, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* c, lapack_int ldc, const lapack_complex_double* d, lapack_int ldd, const lapack_complex_double* e, lapack_int lde, lapack_complex_double* f, lapack_int ldf, double* scale, double* dif, lapack_complex_double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_stpcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const float* ap, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dtpcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const double* ap, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_ctpcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_float* ap, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztpcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_double* ap, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_stprfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* ap, const float* b, lapack_int ldb, const float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dtprfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* ap, const double* b, lapack_int ldb, const double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_ctprfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztprfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_stptri_work( int matrix_order, char uplo, char diag, lapack_int n, float* ap ); lapack_int LAPACKE_dtptri_work( int matrix_order, char uplo, char diag, lapack_int n, double* ap ); lapack_int LAPACKE_ctptri_work( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_float* ap ); lapack_int LAPACKE_ztptri_work( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_double* ap ); lapack_int LAPACKE_stptrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* ap, float* b, lapack_int ldb ); lapack_int LAPACKE_dtptrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* ap, double* b, lapack_int ldb ); lapack_int LAPACKE_ctptrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* ap, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztptrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* ap, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_stpttf_work( int matrix_order, char transr, char uplo, lapack_int n, const float* ap, float* arf ); lapack_int LAPACKE_dtpttf_work( int matrix_order, char transr, char uplo, lapack_int n, const double* ap, double* arf ); lapack_int LAPACKE_ctpttf_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* ap, lapack_complex_float* arf ); lapack_int LAPACKE_ztpttf_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* ap, lapack_complex_double* arf ); lapack_int LAPACKE_stpttr_work( int matrix_order, char uplo, lapack_int n, const float* ap, float* a, lapack_int lda ); lapack_int LAPACKE_dtpttr_work( int matrix_order, char uplo, lapack_int n, const double* ap, double* a, lapack_int lda ); lapack_int LAPACKE_ctpttr_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_ztpttr_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_strcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const float* a, lapack_int lda, float* rcond, float* work, lapack_int* iwork ); lapack_int LAPACKE_dtrcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const double* a, lapack_int lda, double* rcond, double* work, lapack_int* iwork ); lapack_int LAPACKE_ctrcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_float* a, lapack_int lda, float* rcond, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztrcon_work( int matrix_order, char norm, char uplo, char diag, lapack_int n, const lapack_complex_double* a, lapack_int lda, double* rcond, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_strevc_work( int matrix_order, char side, char howmny, lapack_logical* select, lapack_int n, const float* t, lapack_int ldt, float* vl, lapack_int ldvl, float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, float* work ); lapack_int LAPACKE_dtrevc_work( int matrix_order, char side, char howmny, lapack_logical* select, lapack_int n, const double* t, lapack_int ldt, double* vl, lapack_int ldvl, double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, double* work ); lapack_int LAPACKE_ctrevc_work( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* vl, lapack_int ldvl, lapack_complex_float* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztrevc_work( int matrix_order, char side, char howmny, const lapack_logical* select, lapack_int n, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* vl, lapack_int ldvl, lapack_complex_double* vr, lapack_int ldvr, lapack_int mm, lapack_int* m, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_strexc_work( int matrix_order, char compq, lapack_int n, float* t, lapack_int ldt, float* q, lapack_int ldq, lapack_int* ifst, lapack_int* ilst, float* work ); lapack_int LAPACKE_dtrexc_work( int matrix_order, char compq, lapack_int n, double* t, lapack_int ldt, double* q, lapack_int ldq, lapack_int* ifst, lapack_int* ilst, double* work ); lapack_int LAPACKE_ctrexc_work( int matrix_order, char compq, lapack_int n, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* q, lapack_int ldq, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_ztrexc_work( int matrix_order, char compq, lapack_int n, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* q, lapack_int ldq, lapack_int ifst, lapack_int ilst ); lapack_int LAPACKE_strrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const float* b, lapack_int ldb, const float* x, lapack_int ldx, float* ferr, float* berr, float* work, lapack_int* iwork ); lapack_int LAPACKE_dtrrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const double* b, lapack_int ldb, const double* x, lapack_int ldx, double* ferr, double* berr, double* work, lapack_int* iwork ); lapack_int LAPACKE_ctrrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, const lapack_complex_float* x, lapack_int ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork ); lapack_int LAPACKE_ztrrfs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, const lapack_complex_double* x, lapack_int ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork ); lapack_int LAPACKE_strsen_work( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, float* t, lapack_int ldt, float* q, lapack_int ldq, float* wr, float* wi, lapack_int* m, float* s, float* sep, float* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_dtrsen_work( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, double* t, lapack_int ldt, double* q, lapack_int ldq, double* wr, double* wi, lapack_int* m, double* s, double* sep, double* work, lapack_int lwork, lapack_int* iwork, lapack_int liwork ); lapack_int LAPACKE_ctrsen_work( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* w, lapack_int* m, float* s, float* sep, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_ztrsen_work( int matrix_order, char job, char compq, const lapack_logical* select, lapack_int n, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* w, lapack_int* m, double* s, double* sep, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_strsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const float* t, lapack_int ldt, const float* vl, lapack_int ldvl, const float* vr, lapack_int ldvr, float* s, float* sep, lapack_int mm, lapack_int* m, float* work, lapack_int ldwork, lapack_int* iwork ); lapack_int LAPACKE_dtrsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const double* t, lapack_int ldt, const double* vl, lapack_int ldvl, const double* vr, lapack_int ldvr, double* s, double* sep, lapack_int mm, lapack_int* m, double* work, lapack_int ldwork, lapack_int* iwork ); lapack_int LAPACKE_ctrsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_float* t, lapack_int ldt, const lapack_complex_float* vl, lapack_int ldvl, const lapack_complex_float* vr, lapack_int ldvr, float* s, float* sep, lapack_int mm, lapack_int* m, lapack_complex_float* work, lapack_int ldwork, float* rwork ); lapack_int LAPACKE_ztrsna_work( int matrix_order, char job, char howmny, const lapack_logical* select, lapack_int n, const lapack_complex_double* t, lapack_int ldt, const lapack_complex_double* vl, lapack_int ldvl, const lapack_complex_double* vr, lapack_int ldvr, double* s, double* sep, lapack_int mm, lapack_int* m, lapack_complex_double* work, lapack_int ldwork, double* rwork ); lapack_int LAPACKE_strsyl_work( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const float* a, lapack_int lda, const float* b, lapack_int ldb, float* c, lapack_int ldc, float* scale ); lapack_int LAPACKE_dtrsyl_work( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const double* a, lapack_int lda, const double* b, lapack_int ldb, double* c, lapack_int ldc, double* scale ); lapack_int LAPACKE_ctrsyl_work( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* b, lapack_int ldb, lapack_complex_float* c, lapack_int ldc, float* scale ); lapack_int LAPACKE_ztrsyl_work( int matrix_order, char trana, char tranb, lapack_int isgn, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* b, lapack_int ldb, lapack_complex_double* c, lapack_int ldc, double* scale ); lapack_int LAPACKE_strtri_work( int matrix_order, char uplo, char diag, lapack_int n, float* a, lapack_int lda ); lapack_int LAPACKE_dtrtri_work( int matrix_order, char uplo, char diag, lapack_int n, double* a, lapack_int lda ); lapack_int LAPACKE_ctrtri_work( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_ztrtri_work( int matrix_order, char uplo, char diag, lapack_int n, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_strtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dtrtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_ctrtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztrtrs_work( int matrix_order, char uplo, char trans, char diag, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_strttf_work( int matrix_order, char transr, char uplo, lapack_int n, const float* a, lapack_int lda, float* arf ); lapack_int LAPACKE_dtrttf_work( int matrix_order, char transr, char uplo, lapack_int n, const double* a, lapack_int lda, double* arf ); lapack_int LAPACKE_ctrttf_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* arf ); lapack_int LAPACKE_ztrttf_work( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* arf ); lapack_int LAPACKE_strttp_work( int matrix_order, char uplo, lapack_int n, const float* a, lapack_int lda, float* ap ); lapack_int LAPACKE_dtrttp_work( int matrix_order, char uplo, lapack_int n, const double* a, lapack_int lda, double* ap ); lapack_int LAPACKE_ctrttp_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* a, lapack_int lda, lapack_complex_float* ap ); lapack_int LAPACKE_ztrttp_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* a, lapack_int lda, lapack_complex_double* ap ); lapack_int LAPACKE_stzrzf_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* tau, float* work, lapack_int lwork ); lapack_int LAPACKE_dtzrzf_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* tau, double* work, lapack_int lwork ); lapack_int LAPACKE_ctzrzf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_ztzrzf_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cungbr_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zungbr_work( int matrix_order, char vect, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunghr_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunghr_work( int matrix_order, lapack_int n, lapack_int ilo, lapack_int ihi, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunglq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunglq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cungql_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zungql_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cungqr_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zungqr_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cungrq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zungrq_work( int matrix_order, lapack_int m, lapack_int n, lapack_int k, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cungtr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zungtr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmbr_work( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmbr_work( int matrix_order, char vect, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmhr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmhr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int ilo, lapack_int ihi, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmlq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmlq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmql_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmql_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmqr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmqr_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmrq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmrq_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmrz_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmrz_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cunmtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_float* a, lapack_int lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zunmtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_double* a, lapack_int lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_cupgtr_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_float* ap, const lapack_complex_float* tau, lapack_complex_float* q, lapack_int ldq, lapack_complex_float* work ); lapack_int LAPACKE_zupgtr_work( int matrix_order, char uplo, lapack_int n, const lapack_complex_double* ap, const lapack_complex_double* tau, lapack_complex_double* q, lapack_int ldq, lapack_complex_double* work ); lapack_int LAPACKE_cupmtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_float* ap, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work ); lapack_int LAPACKE_zupmtr_work( int matrix_order, char side, char uplo, char trans, lapack_int m, lapack_int n, const lapack_complex_double* ap, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work ); lapack_int LAPACKE_claghe( int matrix_order, lapack_int n, lapack_int k, const float* d, lapack_complex_float* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_zlaghe( int matrix_order, lapack_int n, lapack_int k, const double* d, lapack_complex_double* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_slagsy( int matrix_order, lapack_int n, lapack_int k, const float* d, float* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_dlagsy( int matrix_order, lapack_int n, lapack_int k, const double* d, double* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_clagsy( int matrix_order, lapack_int n, lapack_int k, const float* d, lapack_complex_float* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_zlagsy( int matrix_order, lapack_int n, lapack_int k, const double* d, lapack_complex_double* a, lapack_int lda, lapack_int* iseed ); lapack_int LAPACKE_slapmr( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, float* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_dlapmr( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, double* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_clapmr( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, lapack_complex_float* x, lapack_int ldx, lapack_int* k ); lapack_int LAPACKE_zlapmr( int matrix_order, lapack_logical forwrd, lapack_int m, lapack_int n, lapack_complex_double* x, lapack_int ldx, lapack_int* k ); float LAPACKE_slapy2( float x, float y ); double LAPACKE_dlapy2( double x, double y ); float LAPACKE_slapy3( float x, float y, float z ); double LAPACKE_dlapy3( double x, double y, double z ); lapack_int LAPACKE_slartgp( float f, float g, float* cs, float* sn, float* r ); lapack_int LAPACKE_dlartgp( double f, double g, double* cs, double* sn, double* r ); lapack_int LAPACKE_slartgs( float x, float y, float sigma, float* cs, float* sn ); lapack_int LAPACKE_dlartgs( double x, double y, double sigma, double* cs, double* sn ); //LAPACK 3.3.0 lapack_int LAPACKE_cbbcsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, float* theta, float* phi, lapack_complex_float* u1, lapack_int ldu1, lapack_complex_float* u2, lapack_int ldu2, lapack_complex_float* v1t, lapack_int ldv1t, lapack_complex_float* v2t, lapack_int ldv2t, float* b11d, float* b11e, float* b12d, float* b12e, float* b21d, float* b21e, float* b22d, float* b22e ); lapack_int LAPACKE_cbbcsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, float* theta, float* phi, lapack_complex_float* u1, lapack_int ldu1, lapack_complex_float* u2, lapack_int ldu2, lapack_complex_float* v1t, lapack_int ldv1t, lapack_complex_float* v2t, lapack_int ldv2t, float* b11d, float* b11e, float* b12d, float* b12e, float* b21d, float* b21e, float* b22d, float* b22e, float* rwork, lapack_int lrwork ); lapack_int LAPACKE_cheswapr( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_cheswapr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_chetri2( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_chetri2_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_chetri2x( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_int nb ); lapack_int LAPACKE_chetri2x_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int nb ); lapack_int LAPACKE_chetrs2( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_chetrs2_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work ); lapack_int LAPACKE_csyconv( int matrix_order, char uplo, char way, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_csyconv_work( int matrix_order, char uplo, char way, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work ); lapack_int LAPACKE_csyswapr( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_csyswapr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_csytri2( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_csytri2_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_csytri2x( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_int nb ); lapack_int LAPACKE_csytri2x_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int nb ); lapack_int LAPACKE_csytrs2( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_csytrs2_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work ); lapack_int LAPACKE_cunbdb( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_float* x11, lapack_int ldx11, lapack_complex_float* x12, lapack_int ldx12, lapack_complex_float* x21, lapack_int ldx21, lapack_complex_float* x22, lapack_int ldx22, float* theta, float* phi, lapack_complex_float* taup1, lapack_complex_float* taup2, lapack_complex_float* tauq1, lapack_complex_float* tauq2 ); lapack_int LAPACKE_cunbdb_work( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_float* x11, lapack_int ldx11, lapack_complex_float* x12, lapack_int ldx12, lapack_complex_float* x21, lapack_int ldx21, lapack_complex_float* x22, lapack_int ldx22, float* theta, float* phi, lapack_complex_float* taup1, lapack_complex_float* taup2, lapack_complex_float* tauq1, lapack_complex_float* tauq2, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_cuncsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_float* x11, lapack_int ldx11, lapack_complex_float* x12, lapack_int ldx12, lapack_complex_float* x21, lapack_int ldx21, lapack_complex_float* x22, lapack_int ldx22, float* theta, lapack_complex_float* u1, lapack_int ldu1, lapack_complex_float* u2, lapack_int ldu2, lapack_complex_float* v1t, lapack_int ldv1t, lapack_complex_float* v2t, lapack_int ldv2t ); lapack_int LAPACKE_cuncsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_float* x11, lapack_int ldx11, lapack_complex_float* x12, lapack_int ldx12, lapack_complex_float* x21, lapack_int ldx21, lapack_complex_float* x22, lapack_int ldx22, float* theta, lapack_complex_float* u1, lapack_int ldu1, lapack_complex_float* u2, lapack_int ldu2, lapack_complex_float* v1t, lapack_int ldv1t, lapack_complex_float* v2t, lapack_int ldv2t, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int lrwork, lapack_int* iwork ); lapack_int LAPACKE_dbbcsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, double* theta, double* phi, double* u1, lapack_int ldu1, double* u2, lapack_int ldu2, double* v1t, lapack_int ldv1t, double* v2t, lapack_int ldv2t, double* b11d, double* b11e, double* b12d, double* b12e, double* b21d, double* b21e, double* b22d, double* b22e ); lapack_int LAPACKE_dbbcsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, double* theta, double* phi, double* u1, lapack_int ldu1, double* u2, lapack_int ldu2, double* v1t, lapack_int ldv1t, double* v2t, lapack_int ldv2t, double* b11d, double* b11e, double* b12d, double* b12e, double* b21d, double* b21e, double* b22d, double* b22e, double* work, lapack_int lwork ); lapack_int LAPACKE_dorbdb( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, double* x11, lapack_int ldx11, double* x12, lapack_int ldx12, double* x21, lapack_int ldx21, double* x22, lapack_int ldx22, double* theta, double* phi, double* taup1, double* taup2, double* tauq1, double* tauq2 ); lapack_int LAPACKE_dorbdb_work( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, double* x11, lapack_int ldx11, double* x12, lapack_int ldx12, double* x21, lapack_int ldx21, double* x22, lapack_int ldx22, double* theta, double* phi, double* taup1, double* taup2, double* tauq1, double* tauq2, double* work, lapack_int lwork ); lapack_int LAPACKE_dorcsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, double* x11, lapack_int ldx11, double* x12, lapack_int ldx12, double* x21, lapack_int ldx21, double* x22, lapack_int ldx22, double* theta, double* u1, lapack_int ldu1, double* u2, lapack_int ldu2, double* v1t, lapack_int ldv1t, double* v2t, lapack_int ldv2t ); lapack_int LAPACKE_dorcsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, double* x11, lapack_int ldx11, double* x12, lapack_int ldx12, double* x21, lapack_int ldx21, double* x22, lapack_int ldx22, double* theta, double* u1, lapack_int ldu1, double* u2, lapack_int ldu2, double* v1t, lapack_int ldv1t, double* v2t, lapack_int ldv2t, double* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_dsyconv( int matrix_order, char uplo, char way, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_dsyconv_work( int matrix_order, char uplo, char way, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv, double* work ); lapack_int LAPACKE_dsyswapr( int matrix_order, char uplo, lapack_int n, double* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_dsyswapr_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_dsytri2( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_dsytri2_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_dsytri2x( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv, lapack_int nb ); lapack_int LAPACKE_dsytri2x_work( int matrix_order, char uplo, lapack_int n, double* a, lapack_int lda, const lapack_int* ipiv, double* work, lapack_int nb ); lapack_int LAPACKE_dsytrs2( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_dsytrs2_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const double* a, lapack_int lda, const lapack_int* ipiv, double* b, lapack_int ldb, double* work ); lapack_int LAPACKE_sbbcsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, float* theta, float* phi, float* u1, lapack_int ldu1, float* u2, lapack_int ldu2, float* v1t, lapack_int ldv1t, float* v2t, lapack_int ldv2t, float* b11d, float* b11e, float* b12d, float* b12e, float* b21d, float* b21e, float* b22d, float* b22e ); lapack_int LAPACKE_sbbcsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, float* theta, float* phi, float* u1, lapack_int ldu1, float* u2, lapack_int ldu2, float* v1t, lapack_int ldv1t, float* v2t, lapack_int ldv2t, float* b11d, float* b11e, float* b12d, float* b12e, float* b21d, float* b21e, float* b22d, float* b22e, float* work, lapack_int lwork ); lapack_int LAPACKE_sorbdb( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, float* x11, lapack_int ldx11, float* x12, lapack_int ldx12, float* x21, lapack_int ldx21, float* x22, lapack_int ldx22, float* theta, float* phi, float* taup1, float* taup2, float* tauq1, float* tauq2 ); lapack_int LAPACKE_sorbdb_work( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, float* x11, lapack_int ldx11, float* x12, lapack_int ldx12, float* x21, lapack_int ldx21, float* x22, lapack_int ldx22, float* theta, float* phi, float* taup1, float* taup2, float* tauq1, float* tauq2, float* work, lapack_int lwork ); lapack_int LAPACKE_sorcsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, float* x11, lapack_int ldx11, float* x12, lapack_int ldx12, float* x21, lapack_int ldx21, float* x22, lapack_int ldx22, float* theta, float* u1, lapack_int ldu1, float* u2, lapack_int ldu2, float* v1t, lapack_int ldv1t, float* v2t, lapack_int ldv2t ); lapack_int LAPACKE_sorcsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, float* x11, lapack_int ldx11, float* x12, lapack_int ldx12, float* x21, lapack_int ldx21, float* x22, lapack_int ldx22, float* theta, float* u1, lapack_int ldu1, float* u2, lapack_int ldu2, float* v1t, lapack_int ldv1t, float* v2t, lapack_int ldv2t, float* work, lapack_int lwork, lapack_int* iwork ); lapack_int LAPACKE_ssyconv( int matrix_order, char uplo, char way, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_ssyconv_work( int matrix_order, char uplo, char way, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv, float* work ); lapack_int LAPACKE_ssyswapr( int matrix_order, char uplo, lapack_int n, float* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_ssyswapr_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_ssytri2( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_ssytri2_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_ssytri2x( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv, lapack_int nb ); lapack_int LAPACKE_ssytri2x_work( int matrix_order, char uplo, lapack_int n, float* a, lapack_int lda, const lapack_int* ipiv, float* work, lapack_int nb ); lapack_int LAPACKE_ssytrs2( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_ssytrs2_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const float* a, lapack_int lda, const lapack_int* ipiv, float* b, lapack_int ldb, float* work ); lapack_int LAPACKE_zbbcsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, double* theta, double* phi, lapack_complex_double* u1, lapack_int ldu1, lapack_complex_double* u2, lapack_int ldu2, lapack_complex_double* v1t, lapack_int ldv1t, lapack_complex_double* v2t, lapack_int ldv2t, double* b11d, double* b11e, double* b12d, double* b12e, double* b21d, double* b21e, double* b22d, double* b22e ); lapack_int LAPACKE_zbbcsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, lapack_int m, lapack_int p, lapack_int q, double* theta, double* phi, lapack_complex_double* u1, lapack_int ldu1, lapack_complex_double* u2, lapack_int ldu2, lapack_complex_double* v1t, lapack_int ldv1t, lapack_complex_double* v2t, lapack_int ldv2t, double* b11d, double* b11e, double* b12d, double* b12e, double* b21d, double* b21e, double* b22d, double* b22e, double* rwork, lapack_int lrwork ); lapack_int LAPACKE_zheswapr( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_zheswapr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_zhetri2( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_zhetri2_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_zhetri2x( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_int nb ); lapack_int LAPACKE_zhetri2x_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int nb ); lapack_int LAPACKE_zhetrs2( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_zhetrs2_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work ); lapack_int LAPACKE_zsyconv( int matrix_order, char uplo, char way, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_zsyconv_work( int matrix_order, char uplo, char way, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work ); lapack_int LAPACKE_zsyswapr( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_zsyswapr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int i1, lapack_int i2 ); lapack_int LAPACKE_zsytri2( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv ); lapack_int LAPACKE_zsytri2_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_zsytri2x( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_int nb ); lapack_int LAPACKE_zsytri2x_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int nb ); lapack_int LAPACKE_zsytrs2( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_zsytrs2_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, const lapack_complex_double* a, lapack_int lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work ); lapack_int LAPACKE_zunbdb( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_double* x11, lapack_int ldx11, lapack_complex_double* x12, lapack_int ldx12, lapack_complex_double* x21, lapack_int ldx21, lapack_complex_double* x22, lapack_int ldx22, double* theta, double* phi, lapack_complex_double* taup1, lapack_complex_double* taup2, lapack_complex_double* tauq1, lapack_complex_double* tauq2 ); lapack_int LAPACKE_zunbdb_work( int matrix_order, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_double* x11, lapack_int ldx11, lapack_complex_double* x12, lapack_int ldx12, lapack_complex_double* x21, lapack_int ldx21, lapack_complex_double* x22, lapack_int ldx22, double* theta, double* phi, lapack_complex_double* taup1, lapack_complex_double* taup2, lapack_complex_double* tauq1, lapack_complex_double* tauq2, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_zuncsd( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_double* x11, lapack_int ldx11, lapack_complex_double* x12, lapack_int ldx12, lapack_complex_double* x21, lapack_int ldx21, lapack_complex_double* x22, lapack_int ldx22, double* theta, lapack_complex_double* u1, lapack_int ldu1, lapack_complex_double* u2, lapack_int ldu2, lapack_complex_double* v1t, lapack_int ldv1t, lapack_complex_double* v2t, lapack_int ldv2t ); lapack_int LAPACKE_zuncsd_work( int matrix_order, char jobu1, char jobu2, char jobv1t, char jobv2t, char trans, char signs, lapack_int m, lapack_int p, lapack_int q, lapack_complex_double* x11, lapack_int ldx11, lapack_complex_double* x12, lapack_int ldx12, lapack_complex_double* x21, lapack_int ldx21, lapack_complex_double* x22, lapack_int ldx22, double* theta, lapack_complex_double* u1, lapack_int ldu1, lapack_complex_double* u2, lapack_int ldu2, lapack_complex_double* v1t, lapack_int ldv1t, lapack_complex_double* v2t, lapack_int ldv2t, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int lrwork, lapack_int* iwork ); //LAPACK 3.4.0 lapack_int LAPACKE_sgemqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* c, lapack_int ldc ); lapack_int LAPACKE_dgemqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* c, lapack_int ldc ); lapack_int LAPACKE_cgemqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* c, lapack_int ldc ); lapack_int LAPACKE_zgemqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* c, lapack_int ldc ); lapack_int LAPACKE_sgeqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, float* a, lapack_int lda, float* t, lapack_int ldt ); lapack_int LAPACKE_dgeqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, double* a, lapack_int lda, double* t, lapack_int ldt ); lapack_int LAPACKE_cgeqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, lapack_complex_float* a, lapack_int lda, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zgeqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, lapack_complex_double* a, lapack_int lda, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_sgeqrt2( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* t, lapack_int ldt ); lapack_int LAPACKE_dgeqrt2( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* t, lapack_int ldt ); lapack_int LAPACKE_cgeqrt2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zgeqrt2( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_sgeqrt3( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* t, lapack_int ldt ); lapack_int LAPACKE_dgeqrt3( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* t, lapack_int ldt ); lapack_int LAPACKE_cgeqrt3( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zgeqrt3( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_stpmqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dtpmqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_ctpmqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztpmqrt( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_dtpqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_int nb, double* a, lapack_int lda, double* b, lapack_int ldb, double* t, lapack_int ldt ); lapack_int LAPACKE_ctpqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_int nb, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_ztpqrt( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_int nb, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_stpqrt2( int matrix_order, lapack_int m, lapack_int n, lapack_int l, float* a, lapack_int lda, float* b, lapack_int ldb, float* t, lapack_int ldt ); lapack_int LAPACKE_dtpqrt2( int matrix_order, lapack_int m, lapack_int n, lapack_int l, double* a, lapack_int lda, double* b, lapack_int ldb, double* t, lapack_int ldt ); lapack_int LAPACKE_ctpqrt2( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_ztpqrt2( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_stprfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* a, lapack_int lda, float* b, lapack_int ldb ); lapack_int LAPACKE_dtprfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* a, lapack_int lda, double* b, lapack_int ldb ); lapack_int LAPACKE_ctprfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_ztprfb( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_sgemqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* c, lapack_int ldc, float* work ); lapack_int LAPACKE_dgemqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* c, lapack_int ldc, double* work ); lapack_int LAPACKE_cgemqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* c, lapack_int ldc, lapack_complex_float* work ); lapack_int LAPACKE_zgemqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int nb, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* c, lapack_int ldc, lapack_complex_double* work ); lapack_int LAPACKE_sgeqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, float* a, lapack_int lda, float* t, lapack_int ldt, float* work ); lapack_int LAPACKE_dgeqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, double* a, lapack_int lda, double* t, lapack_int ldt, double* work ); lapack_int LAPACKE_cgeqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, lapack_complex_float* a, lapack_int lda, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* work ); lapack_int LAPACKE_zgeqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int nb, lapack_complex_double* a, lapack_int lda, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* work ); lapack_int LAPACKE_sgeqrt2_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* t, lapack_int ldt ); lapack_int LAPACKE_dgeqrt2_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* t, lapack_int ldt ); lapack_int LAPACKE_cgeqrt2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zgeqrt2_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_sgeqrt3_work( int matrix_order, lapack_int m, lapack_int n, float* a, lapack_int lda, float* t, lapack_int ldt ); lapack_int LAPACKE_dgeqrt3_work( int matrix_order, lapack_int m, lapack_int n, double* a, lapack_int lda, double* t, lapack_int ldt ); lapack_int LAPACKE_cgeqrt3_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_zgeqrt3_work( int matrix_order, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_stpmqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* a, lapack_int lda, float* b, lapack_int ldb, float* work ); lapack_int LAPACKE_dtpmqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* a, lapack_int lda, double* b, lapack_int ldb, double* work ); lapack_int LAPACKE_ctpmqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work ); lapack_int LAPACKE_ztpmqrt_work( int matrix_order, char side, char trans, lapack_int m, lapack_int n, lapack_int k, lapack_int l, lapack_int nb, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work ); lapack_int LAPACKE_dtpqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_int nb, double* a, lapack_int lda, double* b, lapack_int ldb, double* t, lapack_int ldt, double* work ); lapack_int LAPACKE_ctpqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_int nb, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* t, lapack_int ldt, lapack_complex_float* work ); lapack_int LAPACKE_ztpqrt_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_int nb, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* t, lapack_int ldt, lapack_complex_double* work ); lapack_int LAPACKE_stpqrt2_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, float* a, lapack_int lda, float* b, lapack_int ldb, float* t, lapack_int ldt ); lapack_int LAPACKE_dtpqrt2_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, double* a, lapack_int lda, double* b, lapack_int ldb, double* t, lapack_int ldt ); lapack_int LAPACKE_ctpqrt2_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* t, lapack_int ldt ); lapack_int LAPACKE_ztpqrt2_work( int matrix_order, lapack_int m, lapack_int n, lapack_int l, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* t, lapack_int ldt ); lapack_int LAPACKE_stprfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const float* v, lapack_int ldv, const float* t, lapack_int ldt, float* a, lapack_int lda, float* b, lapack_int ldb, const float* work, lapack_int ldwork ); lapack_int LAPACKE_dtprfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const double* v, lapack_int ldv, const double* t, lapack_int ldt, double* a, lapack_int lda, double* b, lapack_int ldb, const double* work, lapack_int ldwork ); lapack_int LAPACKE_ctprfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_float* v, lapack_int ldv, const lapack_complex_float* t, lapack_int ldt, lapack_complex_float* a, lapack_int lda, lapack_complex_float* b, lapack_int ldb, const float* work, lapack_int ldwork ); lapack_int LAPACKE_ztprfb_work( int matrix_order, char side, char trans, char direct, char storev, lapack_int m, lapack_int n, lapack_int k, lapack_int l, const lapack_complex_double* v, lapack_int ldv, const lapack_complex_double* t, lapack_int ldt, lapack_complex_double* a, lapack_int lda, lapack_complex_double* b, lapack_int ldb, const double* work, lapack_int ldwork ); //LAPACK 3.X.X lapack_int LAPACKE_ssysv_rook( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb ); lapack_int LAPACKE_dsysv_rook( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb ); lapack_int LAPACKE_csysv_rook( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb ); lapack_int LAPACKE_zsysv_rook( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb ); lapack_int LAPACKE_csyr( int matrix_order, char uplo, lapack_int n, lapack_complex_float alpha, const lapack_complex_float* x, lapack_int incx, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zsyr( int matrix_order, char uplo, lapack_int n, lapack_complex_double alpha, const lapack_complex_double* x, lapack_int incx, lapack_complex_double* a, lapack_int lda ); lapack_int LAPACKE_ssysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, float* a, lapack_int lda, lapack_int* ipiv, float* b, lapack_int ldb, float* work, lapack_int lwork ); lapack_int LAPACKE_dsysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, double* a, lapack_int lda, lapack_int* ipiv, double* b, lapack_int ldb, double* work, lapack_int lwork ); lapack_int LAPACKE_csysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_float* a, lapack_int lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int ldb, lapack_complex_float* work, lapack_int lwork ); lapack_int LAPACKE_zsysv_rook_work( int matrix_order, char uplo, lapack_int n, lapack_int nrhs, lapack_complex_double* a, lapack_int lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int ldb, lapack_complex_double* work, lapack_int lwork ); lapack_int LAPACKE_csyr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_float alpha, const lapack_complex_float* x, lapack_int incx, lapack_complex_float* a, lapack_int lda ); lapack_int LAPACKE_zsyr_work( int matrix_order, char uplo, lapack_int n, lapack_complex_double alpha, const lapack_complex_double* x, lapack_int incx, lapack_complex_double* a, lapack_int lda ); void LAPACKE_ilaver( const lapack_int* vers_major, const lapack_int* vers_minor, const lapack_int* vers_patch ); #define LAPACK_sgetrf LAPACK_GLOBAL(sgetrf,SGETRF) #define LAPACK_dgetrf LAPACK_GLOBAL(dgetrf,DGETRF) #define LAPACK_cgetrf LAPACK_GLOBAL(cgetrf,CGETRF) #define LAPACK_zgetrf LAPACK_GLOBAL(zgetrf,ZGETRF) #define LAPACK_sgbtrf LAPACK_GLOBAL(sgbtrf,SGBTRF) #define LAPACK_dgbtrf LAPACK_GLOBAL(dgbtrf,DGBTRF) #define LAPACK_cgbtrf LAPACK_GLOBAL(cgbtrf,CGBTRF) #define LAPACK_zgbtrf LAPACK_GLOBAL(zgbtrf,ZGBTRF) #define LAPACK_sgttrf LAPACK_GLOBAL(sgttrf,SGTTRF) #define LAPACK_dgttrf LAPACK_GLOBAL(dgttrf,DGTTRF) #define LAPACK_cgttrf LAPACK_GLOBAL(cgttrf,CGTTRF) #define LAPACK_zgttrf LAPACK_GLOBAL(zgttrf,ZGTTRF) #define LAPACK_spotrf LAPACK_GLOBAL(spotrf,SPOTRF) #define LAPACK_dpotrf LAPACK_GLOBAL(dpotrf,DPOTRF) #define LAPACK_cpotrf LAPACK_GLOBAL(cpotrf,CPOTRF) #define LAPACK_zpotrf LAPACK_GLOBAL(zpotrf,ZPOTRF) #define LAPACK_dpstrf LAPACK_GLOBAL(dpstrf,DPSTRF) #define LAPACK_spstrf LAPACK_GLOBAL(spstrf,SPSTRF) #define LAPACK_zpstrf LAPACK_GLOBAL(zpstrf,ZPSTRF) #define LAPACK_cpstrf LAPACK_GLOBAL(cpstrf,CPSTRF) #define LAPACK_dpftrf LAPACK_GLOBAL(dpftrf,DPFTRF) #define LAPACK_spftrf LAPACK_GLOBAL(spftrf,SPFTRF) #define LAPACK_zpftrf LAPACK_GLOBAL(zpftrf,ZPFTRF) #define LAPACK_cpftrf LAPACK_GLOBAL(cpftrf,CPFTRF) #define LAPACK_spptrf LAPACK_GLOBAL(spptrf,SPPTRF) #define LAPACK_dpptrf LAPACK_GLOBAL(dpptrf,DPPTRF) #define LAPACK_cpptrf LAPACK_GLOBAL(cpptrf,CPPTRF) #define LAPACK_zpptrf LAPACK_GLOBAL(zpptrf,ZPPTRF) #define LAPACK_spbtrf LAPACK_GLOBAL(spbtrf,SPBTRF) #define LAPACK_dpbtrf LAPACK_GLOBAL(dpbtrf,DPBTRF) #define LAPACK_cpbtrf LAPACK_GLOBAL(cpbtrf,CPBTRF) #define LAPACK_zpbtrf LAPACK_GLOBAL(zpbtrf,ZPBTRF) #define LAPACK_spttrf LAPACK_GLOBAL(spttrf,SPTTRF) #define LAPACK_dpttrf LAPACK_GLOBAL(dpttrf,DPTTRF) #define LAPACK_cpttrf LAPACK_GLOBAL(cpttrf,CPTTRF) #define LAPACK_zpttrf LAPACK_GLOBAL(zpttrf,ZPTTRF) #define LAPACK_ssytrf LAPACK_GLOBAL(ssytrf,SSYTRF) #define LAPACK_dsytrf LAPACK_GLOBAL(dsytrf,DSYTRF) #define LAPACK_csytrf LAPACK_GLOBAL(csytrf,CSYTRF) #define LAPACK_zsytrf LAPACK_GLOBAL(zsytrf,ZSYTRF) #define LAPACK_chetrf LAPACK_GLOBAL(chetrf,CHETRF) #define LAPACK_zhetrf LAPACK_GLOBAL(zhetrf,ZHETRF) #define LAPACK_ssptrf LAPACK_GLOBAL(ssptrf,SSPTRF) #define LAPACK_dsptrf LAPACK_GLOBAL(dsptrf,DSPTRF) #define LAPACK_csptrf LAPACK_GLOBAL(csptrf,CSPTRF) #define LAPACK_zsptrf LAPACK_GLOBAL(zsptrf,ZSPTRF) #define LAPACK_chptrf LAPACK_GLOBAL(chptrf,CHPTRF) #define LAPACK_zhptrf LAPACK_GLOBAL(zhptrf,ZHPTRF) #define LAPACK_sgetrs LAPACK_GLOBAL(sgetrs,SGETRS) #define LAPACK_dgetrs LAPACK_GLOBAL(dgetrs,DGETRS) #define LAPACK_cgetrs LAPACK_GLOBAL(cgetrs,CGETRS) #define LAPACK_zgetrs LAPACK_GLOBAL(zgetrs,ZGETRS) #define LAPACK_sgbtrs LAPACK_GLOBAL(sgbtrs,SGBTRS) #define LAPACK_dgbtrs LAPACK_GLOBAL(dgbtrs,DGBTRS) #define LAPACK_cgbtrs LAPACK_GLOBAL(cgbtrs,CGBTRS) #define LAPACK_zgbtrs LAPACK_GLOBAL(zgbtrs,ZGBTRS) #define LAPACK_sgttrs LAPACK_GLOBAL(sgttrs,SGTTRS) #define LAPACK_dgttrs LAPACK_GLOBAL(dgttrs,DGTTRS) #define LAPACK_cgttrs LAPACK_GLOBAL(cgttrs,CGTTRS) #define LAPACK_zgttrs LAPACK_GLOBAL(zgttrs,ZGTTRS) #define LAPACK_spotrs LAPACK_GLOBAL(spotrs,SPOTRS) #define LAPACK_dpotrs LAPACK_GLOBAL(dpotrs,DPOTRS) #define LAPACK_cpotrs LAPACK_GLOBAL(cpotrs,CPOTRS) #define LAPACK_zpotrs LAPACK_GLOBAL(zpotrs,ZPOTRS) #define LAPACK_dpftrs LAPACK_GLOBAL(dpftrs,DPFTRS) #define LAPACK_spftrs LAPACK_GLOBAL(spftrs,SPFTRS) #define LAPACK_zpftrs LAPACK_GLOBAL(zpftrs,ZPFTRS) #define LAPACK_cpftrs LAPACK_GLOBAL(cpftrs,CPFTRS) #define LAPACK_spptrs LAPACK_GLOBAL(spptrs,SPPTRS) #define LAPACK_dpptrs LAPACK_GLOBAL(dpptrs,DPPTRS) #define LAPACK_cpptrs LAPACK_GLOBAL(cpptrs,CPPTRS) #define LAPACK_zpptrs LAPACK_GLOBAL(zpptrs,ZPPTRS) #define LAPACK_spbtrs LAPACK_GLOBAL(spbtrs,SPBTRS) #define LAPACK_dpbtrs LAPACK_GLOBAL(dpbtrs,DPBTRS) #define LAPACK_cpbtrs LAPACK_GLOBAL(cpbtrs,CPBTRS) #define LAPACK_zpbtrs LAPACK_GLOBAL(zpbtrs,ZPBTRS) #define LAPACK_spttrs LAPACK_GLOBAL(spttrs,SPTTRS) #define LAPACK_dpttrs LAPACK_GLOBAL(dpttrs,DPTTRS) #define LAPACK_cpttrs LAPACK_GLOBAL(cpttrs,CPTTRS) #define LAPACK_zpttrs LAPACK_GLOBAL(zpttrs,ZPTTRS) #define LAPACK_ssytrs LAPACK_GLOBAL(ssytrs,SSYTRS) #define LAPACK_dsytrs LAPACK_GLOBAL(dsytrs,DSYTRS) #define LAPACK_csytrs LAPACK_GLOBAL(csytrs,CSYTRS) #define LAPACK_zsytrs LAPACK_GLOBAL(zsytrs,ZSYTRS) #define LAPACK_chetrs LAPACK_GLOBAL(chetrs,CHETRS) #define LAPACK_zhetrs LAPACK_GLOBAL(zhetrs,ZHETRS) #define LAPACK_ssptrs LAPACK_GLOBAL(ssptrs,SSPTRS) #define LAPACK_dsptrs LAPACK_GLOBAL(dsptrs,DSPTRS) #define LAPACK_csptrs LAPACK_GLOBAL(csptrs,CSPTRS) #define LAPACK_zsptrs LAPACK_GLOBAL(zsptrs,ZSPTRS) #define LAPACK_chptrs LAPACK_GLOBAL(chptrs,CHPTRS) #define LAPACK_zhptrs LAPACK_GLOBAL(zhptrs,ZHPTRS) #define LAPACK_strtrs LAPACK_GLOBAL(strtrs,STRTRS) #define LAPACK_dtrtrs LAPACK_GLOBAL(dtrtrs,DTRTRS) #define LAPACK_ctrtrs LAPACK_GLOBAL(ctrtrs,CTRTRS) #define LAPACK_ztrtrs LAPACK_GLOBAL(ztrtrs,ZTRTRS) #define LAPACK_stptrs LAPACK_GLOBAL(stptrs,STPTRS) #define LAPACK_dtptrs LAPACK_GLOBAL(dtptrs,DTPTRS) #define LAPACK_ctptrs LAPACK_GLOBAL(ctptrs,CTPTRS) #define LAPACK_ztptrs LAPACK_GLOBAL(ztptrs,ZTPTRS) #define LAPACK_stbtrs LAPACK_GLOBAL(stbtrs,STBTRS) #define LAPACK_dtbtrs LAPACK_GLOBAL(dtbtrs,DTBTRS) #define LAPACK_ctbtrs LAPACK_GLOBAL(ctbtrs,CTBTRS) #define LAPACK_ztbtrs LAPACK_GLOBAL(ztbtrs,ZTBTRS) #define LAPACK_sgecon LAPACK_GLOBAL(sgecon,SGECON) #define LAPACK_dgecon LAPACK_GLOBAL(dgecon,DGECON) #define LAPACK_cgecon LAPACK_GLOBAL(cgecon,CGECON) #define LAPACK_zgecon LAPACK_GLOBAL(zgecon,ZGECON) #define LAPACK_sgbcon LAPACK_GLOBAL(sgbcon,SGBCON) #define LAPACK_dgbcon LAPACK_GLOBAL(dgbcon,DGBCON) #define LAPACK_cgbcon LAPACK_GLOBAL(cgbcon,CGBCON) #define LAPACK_zgbcon LAPACK_GLOBAL(zgbcon,ZGBCON) #define LAPACK_sgtcon LAPACK_GLOBAL(sgtcon,SGTCON) #define LAPACK_dgtcon LAPACK_GLOBAL(dgtcon,DGTCON) #define LAPACK_cgtcon LAPACK_GLOBAL(cgtcon,CGTCON) #define LAPACK_zgtcon LAPACK_GLOBAL(zgtcon,ZGTCON) #define LAPACK_spocon LAPACK_GLOBAL(spocon,SPOCON) #define LAPACK_dpocon LAPACK_GLOBAL(dpocon,DPOCON) #define LAPACK_cpocon LAPACK_GLOBAL(cpocon,CPOCON) #define LAPACK_zpocon LAPACK_GLOBAL(zpocon,ZPOCON) #define LAPACK_sppcon LAPACK_GLOBAL(sppcon,SPPCON) #define LAPACK_dppcon LAPACK_GLOBAL(dppcon,DPPCON) #define LAPACK_cppcon LAPACK_GLOBAL(cppcon,CPPCON) #define LAPACK_zppcon LAPACK_GLOBAL(zppcon,ZPPCON) #define LAPACK_spbcon LAPACK_GLOBAL(spbcon,SPBCON) #define LAPACK_dpbcon LAPACK_GLOBAL(dpbcon,DPBCON) #define LAPACK_cpbcon LAPACK_GLOBAL(cpbcon,CPBCON) #define LAPACK_zpbcon LAPACK_GLOBAL(zpbcon,ZPBCON) #define LAPACK_sptcon LAPACK_GLOBAL(sptcon,SPTCON) #define LAPACK_dptcon LAPACK_GLOBAL(dptcon,DPTCON) #define LAPACK_cptcon LAPACK_GLOBAL(cptcon,CPTCON) #define LAPACK_zptcon LAPACK_GLOBAL(zptcon,ZPTCON) #define LAPACK_ssycon LAPACK_GLOBAL(ssycon,SSYCON) #define LAPACK_dsycon LAPACK_GLOBAL(dsycon,DSYCON) #define LAPACK_csycon LAPACK_GLOBAL(csycon,CSYCON) #define LAPACK_zsycon LAPACK_GLOBAL(zsycon,ZSYCON) #define LAPACK_checon LAPACK_GLOBAL(checon,CHECON) #define LAPACK_zhecon LAPACK_GLOBAL(zhecon,ZHECON) #define LAPACK_sspcon LAPACK_GLOBAL(sspcon,SSPCON) #define LAPACK_dspcon LAPACK_GLOBAL(dspcon,DSPCON) #define LAPACK_cspcon LAPACK_GLOBAL(cspcon,CSPCON) #define LAPACK_zspcon LAPACK_GLOBAL(zspcon,ZSPCON) #define LAPACK_chpcon LAPACK_GLOBAL(chpcon,CHPCON) #define LAPACK_zhpcon LAPACK_GLOBAL(zhpcon,ZHPCON) #define LAPACK_strcon LAPACK_GLOBAL(strcon,STRCON) #define LAPACK_dtrcon LAPACK_GLOBAL(dtrcon,DTRCON) #define LAPACK_ctrcon LAPACK_GLOBAL(ctrcon,CTRCON) #define LAPACK_ztrcon LAPACK_GLOBAL(ztrcon,ZTRCON) #define LAPACK_stpcon LAPACK_GLOBAL(stpcon,STPCON) #define LAPACK_dtpcon LAPACK_GLOBAL(dtpcon,DTPCON) #define LAPACK_ctpcon LAPACK_GLOBAL(ctpcon,CTPCON) #define LAPACK_ztpcon LAPACK_GLOBAL(ztpcon,ZTPCON) #define LAPACK_stbcon LAPACK_GLOBAL(stbcon,STBCON) #define LAPACK_dtbcon LAPACK_GLOBAL(dtbcon,DTBCON) #define LAPACK_ctbcon LAPACK_GLOBAL(ctbcon,CTBCON) #define LAPACK_ztbcon LAPACK_GLOBAL(ztbcon,ZTBCON) #define LAPACK_sgerfs LAPACK_GLOBAL(sgerfs,SGERFS) #define LAPACK_dgerfs LAPACK_GLOBAL(dgerfs,DGERFS) #define LAPACK_cgerfs LAPACK_GLOBAL(cgerfs,CGERFS) #define LAPACK_zgerfs LAPACK_GLOBAL(zgerfs,ZGERFS) #define LAPACK_dgerfsx LAPACK_GLOBAL(dgerfsx,DGERFSX) #define LAPACK_sgerfsx LAPACK_GLOBAL(sgerfsx,SGERFSX) #define LAPACK_zgerfsx LAPACK_GLOBAL(zgerfsx,ZGERFSX) #define LAPACK_cgerfsx LAPACK_GLOBAL(cgerfsx,CGERFSX) #define LAPACK_sgbrfs LAPACK_GLOBAL(sgbrfs,SGBRFS) #define LAPACK_dgbrfs LAPACK_GLOBAL(dgbrfs,DGBRFS) #define LAPACK_cgbrfs LAPACK_GLOBAL(cgbrfs,CGBRFS) #define LAPACK_zgbrfs LAPACK_GLOBAL(zgbrfs,ZGBRFS) #define LAPACK_dgbrfsx LAPACK_GLOBAL(dgbrfsx,DGBRFSX) #define LAPACK_sgbrfsx LAPACK_GLOBAL(sgbrfsx,SGBRFSX) #define LAPACK_zgbrfsx LAPACK_GLOBAL(zgbrfsx,ZGBRFSX) #define LAPACK_cgbrfsx LAPACK_GLOBAL(cgbrfsx,CGBRFSX) #define LAPACK_sgtrfs LAPACK_GLOBAL(sgtrfs,SGTRFS) #define LAPACK_dgtrfs LAPACK_GLOBAL(dgtrfs,DGTRFS) #define LAPACK_cgtrfs LAPACK_GLOBAL(cgtrfs,CGTRFS) #define LAPACK_zgtrfs LAPACK_GLOBAL(zgtrfs,ZGTRFS) #define LAPACK_sporfs LAPACK_GLOBAL(sporfs,SPORFS) #define LAPACK_dporfs LAPACK_GLOBAL(dporfs,DPORFS) #define LAPACK_cporfs LAPACK_GLOBAL(cporfs,CPORFS) #define LAPACK_zporfs LAPACK_GLOBAL(zporfs,ZPORFS) #define LAPACK_dporfsx LAPACK_GLOBAL(dporfsx,DPORFSX) #define LAPACK_sporfsx LAPACK_GLOBAL(sporfsx,SPORFSX) #define LAPACK_zporfsx LAPACK_GLOBAL(zporfsx,ZPORFSX) #define LAPACK_cporfsx LAPACK_GLOBAL(cporfsx,CPORFSX) #define LAPACK_spprfs LAPACK_GLOBAL(spprfs,SPPRFS) #define LAPACK_dpprfs LAPACK_GLOBAL(dpprfs,DPPRFS) #define LAPACK_cpprfs LAPACK_GLOBAL(cpprfs,CPPRFS) #define LAPACK_zpprfs LAPACK_GLOBAL(zpprfs,ZPPRFS) #define LAPACK_spbrfs LAPACK_GLOBAL(spbrfs,SPBRFS) #define LAPACK_dpbrfs LAPACK_GLOBAL(dpbrfs,DPBRFS) #define LAPACK_cpbrfs LAPACK_GLOBAL(cpbrfs,CPBRFS) #define LAPACK_zpbrfs LAPACK_GLOBAL(zpbrfs,ZPBRFS) #define LAPACK_sptrfs LAPACK_GLOBAL(sptrfs,SPTRFS) #define LAPACK_dptrfs LAPACK_GLOBAL(dptrfs,DPTRFS) #define LAPACK_cptrfs LAPACK_GLOBAL(cptrfs,CPTRFS) #define LAPACK_zptrfs LAPACK_GLOBAL(zptrfs,ZPTRFS) #define LAPACK_ssyrfs LAPACK_GLOBAL(ssyrfs,SSYRFS) #define LAPACK_dsyrfs LAPACK_GLOBAL(dsyrfs,DSYRFS) #define LAPACK_csyrfs LAPACK_GLOBAL(csyrfs,CSYRFS) #define LAPACK_zsyrfs LAPACK_GLOBAL(zsyrfs,ZSYRFS) #define LAPACK_dsyrfsx LAPACK_GLOBAL(dsyrfsx,DSYRFSX) #define LAPACK_ssyrfsx LAPACK_GLOBAL(ssyrfsx,SSYRFSX) #define LAPACK_zsyrfsx LAPACK_GLOBAL(zsyrfsx,ZSYRFSX) #define LAPACK_csyrfsx LAPACK_GLOBAL(csyrfsx,CSYRFSX) #define LAPACK_cherfs LAPACK_GLOBAL(cherfs,CHERFS) #define LAPACK_zherfs LAPACK_GLOBAL(zherfs,ZHERFS) #define LAPACK_zherfsx LAPACK_GLOBAL(zherfsx,ZHERFSX) #define LAPACK_cherfsx LAPACK_GLOBAL(cherfsx,CHERFSX) #define LAPACK_ssprfs LAPACK_GLOBAL(ssprfs,SSPRFS) #define LAPACK_dsprfs LAPACK_GLOBAL(dsprfs,DSPRFS) #define LAPACK_csprfs LAPACK_GLOBAL(csprfs,CSPRFS) #define LAPACK_zsprfs LAPACK_GLOBAL(zsprfs,ZSPRFS) #define LAPACK_chprfs LAPACK_GLOBAL(chprfs,CHPRFS) #define LAPACK_zhprfs LAPACK_GLOBAL(zhprfs,ZHPRFS) #define LAPACK_strrfs LAPACK_GLOBAL(strrfs,STRRFS) #define LAPACK_dtrrfs LAPACK_GLOBAL(dtrrfs,DTRRFS) #define LAPACK_ctrrfs LAPACK_GLOBAL(ctrrfs,CTRRFS) #define LAPACK_ztrrfs LAPACK_GLOBAL(ztrrfs,ZTRRFS) #define LAPACK_stprfs LAPACK_GLOBAL(stprfs,STPRFS) #define LAPACK_dtprfs LAPACK_GLOBAL(dtprfs,DTPRFS) #define LAPACK_ctprfs LAPACK_GLOBAL(ctprfs,CTPRFS) #define LAPACK_ztprfs LAPACK_GLOBAL(ztprfs,ZTPRFS) #define LAPACK_stbrfs LAPACK_GLOBAL(stbrfs,STBRFS) #define LAPACK_dtbrfs LAPACK_GLOBAL(dtbrfs,DTBRFS) #define LAPACK_ctbrfs LAPACK_GLOBAL(ctbrfs,CTBRFS) #define LAPACK_ztbrfs LAPACK_GLOBAL(ztbrfs,ZTBRFS) #define LAPACK_sgetri LAPACK_GLOBAL(sgetri,SGETRI) #define LAPACK_dgetri LAPACK_GLOBAL(dgetri,DGETRI) #define LAPACK_cgetri LAPACK_GLOBAL(cgetri,CGETRI) #define LAPACK_zgetri LAPACK_GLOBAL(zgetri,ZGETRI) #define LAPACK_spotri LAPACK_GLOBAL(spotri,SPOTRI) #define LAPACK_dpotri LAPACK_GLOBAL(dpotri,DPOTRI) #define LAPACK_cpotri LAPACK_GLOBAL(cpotri,CPOTRI) #define LAPACK_zpotri LAPACK_GLOBAL(zpotri,ZPOTRI) #define LAPACK_dpftri LAPACK_GLOBAL(dpftri,DPFTRI) #define LAPACK_spftri LAPACK_GLOBAL(spftri,SPFTRI) #define LAPACK_zpftri LAPACK_GLOBAL(zpftri,ZPFTRI) #define LAPACK_cpftri LAPACK_GLOBAL(cpftri,CPFTRI) #define LAPACK_spptri LAPACK_GLOBAL(spptri,SPPTRI) #define LAPACK_dpptri LAPACK_GLOBAL(dpptri,DPPTRI) #define LAPACK_cpptri LAPACK_GLOBAL(cpptri,CPPTRI) #define LAPACK_zpptri LAPACK_GLOBAL(zpptri,ZPPTRI) #define LAPACK_ssytri LAPACK_GLOBAL(ssytri,SSYTRI) #define LAPACK_dsytri LAPACK_GLOBAL(dsytri,DSYTRI) #define LAPACK_csytri LAPACK_GLOBAL(csytri,CSYTRI) #define LAPACK_zsytri LAPACK_GLOBAL(zsytri,ZSYTRI) #define LAPACK_chetri LAPACK_GLOBAL(chetri,CHETRI) #define LAPACK_zhetri LAPACK_GLOBAL(zhetri,ZHETRI) #define LAPACK_ssptri LAPACK_GLOBAL(ssptri,SSPTRI) #define LAPACK_dsptri LAPACK_GLOBAL(dsptri,DSPTRI) #define LAPACK_csptri LAPACK_GLOBAL(csptri,CSPTRI) #define LAPACK_zsptri LAPACK_GLOBAL(zsptri,ZSPTRI) #define LAPACK_chptri LAPACK_GLOBAL(chptri,CHPTRI) #define LAPACK_zhptri LAPACK_GLOBAL(zhptri,ZHPTRI) #define LAPACK_strtri LAPACK_GLOBAL(strtri,STRTRI) #define LAPACK_dtrtri LAPACK_GLOBAL(dtrtri,DTRTRI) #define LAPACK_ctrtri LAPACK_GLOBAL(ctrtri,CTRTRI) #define LAPACK_ztrtri LAPACK_GLOBAL(ztrtri,ZTRTRI) #define LAPACK_dtftri LAPACK_GLOBAL(dtftri,DTFTRI) #define LAPACK_stftri LAPACK_GLOBAL(stftri,STFTRI) #define LAPACK_ztftri LAPACK_GLOBAL(ztftri,ZTFTRI) #define LAPACK_ctftri LAPACK_GLOBAL(ctftri,CTFTRI) #define LAPACK_stptri LAPACK_GLOBAL(stptri,STPTRI) #define LAPACK_dtptri LAPACK_GLOBAL(dtptri,DTPTRI) #define LAPACK_ctptri LAPACK_GLOBAL(ctptri,CTPTRI) #define LAPACK_ztptri LAPACK_GLOBAL(ztptri,ZTPTRI) #define LAPACK_sgeequ LAPACK_GLOBAL(sgeequ,SGEEQU) #define LAPACK_dgeequ LAPACK_GLOBAL(dgeequ,DGEEQU) #define LAPACK_cgeequ LAPACK_GLOBAL(cgeequ,CGEEQU) #define LAPACK_zgeequ LAPACK_GLOBAL(zgeequ,ZGEEQU) #define LAPACK_dgeequb LAPACK_GLOBAL(dgeequb,DGEEQUB) #define LAPACK_sgeequb LAPACK_GLOBAL(sgeequb,SGEEQUB) #define LAPACK_zgeequb LAPACK_GLOBAL(zgeequb,ZGEEQUB) #define LAPACK_cgeequb LAPACK_GLOBAL(cgeequb,CGEEQUB) #define LAPACK_sgbequ LAPACK_GLOBAL(sgbequ,SGBEQU) #define LAPACK_dgbequ LAPACK_GLOBAL(dgbequ,DGBEQU) #define LAPACK_cgbequ LAPACK_GLOBAL(cgbequ,CGBEQU) #define LAPACK_zgbequ LAPACK_GLOBAL(zgbequ,ZGBEQU) #define LAPACK_dgbequb LAPACK_GLOBAL(dgbequb,DGBEQUB) #define LAPACK_sgbequb LAPACK_GLOBAL(sgbequb,SGBEQUB) #define LAPACK_zgbequb LAPACK_GLOBAL(zgbequb,ZGBEQUB) #define LAPACK_cgbequb LAPACK_GLOBAL(cgbequb,CGBEQUB) #define LAPACK_spoequ LAPACK_GLOBAL(spoequ,SPOEQU) #define LAPACK_dpoequ LAPACK_GLOBAL(dpoequ,DPOEQU) #define LAPACK_cpoequ LAPACK_GLOBAL(cpoequ,CPOEQU) #define LAPACK_zpoequ LAPACK_GLOBAL(zpoequ,ZPOEQU) #define LAPACK_dpoequb LAPACK_GLOBAL(dpoequb,DPOEQUB) #define LAPACK_spoequb LAPACK_GLOBAL(spoequb,SPOEQUB) #define LAPACK_zpoequb LAPACK_GLOBAL(zpoequb,ZPOEQUB) #define LAPACK_cpoequb LAPACK_GLOBAL(cpoequb,CPOEQUB) #define LAPACK_sppequ LAPACK_GLOBAL(sppequ,SPPEQU) #define LAPACK_dppequ LAPACK_GLOBAL(dppequ,DPPEQU) #define LAPACK_cppequ LAPACK_GLOBAL(cppequ,CPPEQU) #define LAPACK_zppequ LAPACK_GLOBAL(zppequ,ZPPEQU) #define LAPACK_spbequ LAPACK_GLOBAL(spbequ,SPBEQU) #define LAPACK_dpbequ LAPACK_GLOBAL(dpbequ,DPBEQU) #define LAPACK_cpbequ LAPACK_GLOBAL(cpbequ,CPBEQU) #define LAPACK_zpbequ LAPACK_GLOBAL(zpbequ,ZPBEQU) #define LAPACK_dsyequb LAPACK_GLOBAL(dsyequb,DSYEQUB) #define LAPACK_ssyequb LAPACK_GLOBAL(ssyequb,SSYEQUB) #define LAPACK_zsyequb LAPACK_GLOBAL(zsyequb,ZSYEQUB) #define LAPACK_csyequb LAPACK_GLOBAL(csyequb,CSYEQUB) #define LAPACK_zheequb LAPACK_GLOBAL(zheequb,ZHEEQUB) #define LAPACK_cheequb LAPACK_GLOBAL(cheequb,CHEEQUB) #define LAPACK_sgesv LAPACK_GLOBAL(sgesv,SGESV) #define LAPACK_dgesv LAPACK_GLOBAL(dgesv,DGESV) #define LAPACK_cgesv LAPACK_GLOBAL(cgesv,CGESV) #define LAPACK_zgesv LAPACK_GLOBAL(zgesv,ZGESV) #define LAPACK_dsgesv LAPACK_GLOBAL(dsgesv,DSGESV) #define LAPACK_zcgesv LAPACK_GLOBAL(zcgesv,ZCGESV) #define LAPACK_sgesvx LAPACK_GLOBAL(sgesvx,SGESVX) #define LAPACK_dgesvx LAPACK_GLOBAL(dgesvx,DGESVX) #define LAPACK_cgesvx LAPACK_GLOBAL(cgesvx,CGESVX) #define LAPACK_zgesvx LAPACK_GLOBAL(zgesvx,ZGESVX) #define LAPACK_dgesvxx LAPACK_GLOBAL(dgesvxx,DGESVXX) #define LAPACK_sgesvxx LAPACK_GLOBAL(sgesvxx,SGESVXX) #define LAPACK_zgesvxx LAPACK_GLOBAL(zgesvxx,ZGESVXX) #define LAPACK_cgesvxx LAPACK_GLOBAL(cgesvxx,CGESVXX) #define LAPACK_sgbsv LAPACK_GLOBAL(sgbsv,SGBSV) #define LAPACK_dgbsv LAPACK_GLOBAL(dgbsv,DGBSV) #define LAPACK_cgbsv LAPACK_GLOBAL(cgbsv,CGBSV) #define LAPACK_zgbsv LAPACK_GLOBAL(zgbsv,ZGBSV) #define LAPACK_sgbsvx LAPACK_GLOBAL(sgbsvx,SGBSVX) #define LAPACK_dgbsvx LAPACK_GLOBAL(dgbsvx,DGBSVX) #define LAPACK_cgbsvx LAPACK_GLOBAL(cgbsvx,CGBSVX) #define LAPACK_zgbsvx LAPACK_GLOBAL(zgbsvx,ZGBSVX) #define LAPACK_dgbsvxx LAPACK_GLOBAL(dgbsvxx,DGBSVXX) #define LAPACK_sgbsvxx LAPACK_GLOBAL(sgbsvxx,SGBSVXX) #define LAPACK_zgbsvxx LAPACK_GLOBAL(zgbsvxx,ZGBSVXX) #define LAPACK_cgbsvxx LAPACK_GLOBAL(cgbsvxx,CGBSVXX) #define LAPACK_sgtsv LAPACK_GLOBAL(sgtsv,SGTSV) #define LAPACK_dgtsv LAPACK_GLOBAL(dgtsv,DGTSV) #define LAPACK_cgtsv LAPACK_GLOBAL(cgtsv,CGTSV) #define LAPACK_zgtsv LAPACK_GLOBAL(zgtsv,ZGTSV) #define LAPACK_sgtsvx LAPACK_GLOBAL(sgtsvx,SGTSVX) #define LAPACK_dgtsvx LAPACK_GLOBAL(dgtsvx,DGTSVX) #define LAPACK_cgtsvx LAPACK_GLOBAL(cgtsvx,CGTSVX) #define LAPACK_zgtsvx LAPACK_GLOBAL(zgtsvx,ZGTSVX) #define LAPACK_sposv LAPACK_GLOBAL(sposv,SPOSV) #define LAPACK_dposv LAPACK_GLOBAL(dposv,DPOSV) #define LAPACK_cposv LAPACK_GLOBAL(cposv,CPOSV) #define LAPACK_zposv LAPACK_GLOBAL(zposv,ZPOSV) #define LAPACK_dsposv LAPACK_GLOBAL(dsposv,DSPOSV) #define LAPACK_zcposv LAPACK_GLOBAL(zcposv,ZCPOSV) #define LAPACK_sposvx LAPACK_GLOBAL(sposvx,SPOSVX) #define LAPACK_dposvx LAPACK_GLOBAL(dposvx,DPOSVX) #define LAPACK_cposvx LAPACK_GLOBAL(cposvx,CPOSVX) #define LAPACK_zposvx LAPACK_GLOBAL(zposvx,ZPOSVX) #define LAPACK_dposvxx LAPACK_GLOBAL(dposvxx,DPOSVXX) #define LAPACK_sposvxx LAPACK_GLOBAL(sposvxx,SPOSVXX) #define LAPACK_zposvxx LAPACK_GLOBAL(zposvxx,ZPOSVXX) #define LAPACK_cposvxx LAPACK_GLOBAL(cposvxx,CPOSVXX) #define LAPACK_sppsv LAPACK_GLOBAL(sppsv,SPPSV) #define LAPACK_dppsv LAPACK_GLOBAL(dppsv,DPPSV) #define LAPACK_cppsv LAPACK_GLOBAL(cppsv,CPPSV) #define LAPACK_zppsv LAPACK_GLOBAL(zppsv,ZPPSV) #define LAPACK_sppsvx LAPACK_GLOBAL(sppsvx,SPPSVX) #define LAPACK_dppsvx LAPACK_GLOBAL(dppsvx,DPPSVX) #define LAPACK_cppsvx LAPACK_GLOBAL(cppsvx,CPPSVX) #define LAPACK_zppsvx LAPACK_GLOBAL(zppsvx,ZPPSVX) #define LAPACK_spbsv LAPACK_GLOBAL(spbsv,SPBSV) #define LAPACK_dpbsv LAPACK_GLOBAL(dpbsv,DPBSV) #define LAPACK_cpbsv LAPACK_GLOBAL(cpbsv,CPBSV) #define LAPACK_zpbsv LAPACK_GLOBAL(zpbsv,ZPBSV) #define LAPACK_spbsvx LAPACK_GLOBAL(spbsvx,SPBSVX) #define LAPACK_dpbsvx LAPACK_GLOBAL(dpbsvx,DPBSVX) #define LAPACK_cpbsvx LAPACK_GLOBAL(cpbsvx,CPBSVX) #define LAPACK_zpbsvx LAPACK_GLOBAL(zpbsvx,ZPBSVX) #define LAPACK_sptsv LAPACK_GLOBAL(sptsv,SPTSV) #define LAPACK_dptsv LAPACK_GLOBAL(dptsv,DPTSV) #define LAPACK_cptsv LAPACK_GLOBAL(cptsv,CPTSV) #define LAPACK_zptsv LAPACK_GLOBAL(zptsv,ZPTSV) #define LAPACK_sptsvx LAPACK_GLOBAL(sptsvx,SPTSVX) #define LAPACK_dptsvx LAPACK_GLOBAL(dptsvx,DPTSVX) #define LAPACK_cptsvx LAPACK_GLOBAL(cptsvx,CPTSVX) #define LAPACK_zptsvx LAPACK_GLOBAL(zptsvx,ZPTSVX) #define LAPACK_ssysv LAPACK_GLOBAL(ssysv,SSYSV) #define LAPACK_dsysv LAPACK_GLOBAL(dsysv,DSYSV) #define LAPACK_csysv LAPACK_GLOBAL(csysv,CSYSV) #define LAPACK_zsysv LAPACK_GLOBAL(zsysv,ZSYSV) #define LAPACK_ssysvx LAPACK_GLOBAL(ssysvx,SSYSVX) #define LAPACK_dsysvx LAPACK_GLOBAL(dsysvx,DSYSVX) #define LAPACK_csysvx LAPACK_GLOBAL(csysvx,CSYSVX) #define LAPACK_zsysvx LAPACK_GLOBAL(zsysvx,ZSYSVX) #define LAPACK_dsysvxx LAPACK_GLOBAL(dsysvxx,DSYSVXX) #define LAPACK_ssysvxx LAPACK_GLOBAL(ssysvxx,SSYSVXX) #define LAPACK_zsysvxx LAPACK_GLOBAL(zsysvxx,ZSYSVXX) #define LAPACK_csysvxx LAPACK_GLOBAL(csysvxx,CSYSVXX) #define LAPACK_chesv LAPACK_GLOBAL(chesv,CHESV) #define LAPACK_zhesv LAPACK_GLOBAL(zhesv,ZHESV) #define LAPACK_chesvx LAPACK_GLOBAL(chesvx,CHESVX) #define LAPACK_zhesvx LAPACK_GLOBAL(zhesvx,ZHESVX) #define LAPACK_zhesvxx LAPACK_GLOBAL(zhesvxx,ZHESVXX) #define LAPACK_chesvxx LAPACK_GLOBAL(chesvxx,CHESVXX) #define LAPACK_sspsv LAPACK_GLOBAL(sspsv,SSPSV) #define LAPACK_dspsv LAPACK_GLOBAL(dspsv,DSPSV) #define LAPACK_cspsv LAPACK_GLOBAL(cspsv,CSPSV) #define LAPACK_zspsv LAPACK_GLOBAL(zspsv,ZSPSV) #define LAPACK_sspsvx LAPACK_GLOBAL(sspsvx,SSPSVX) #define LAPACK_dspsvx LAPACK_GLOBAL(dspsvx,DSPSVX) #define LAPACK_cspsvx LAPACK_GLOBAL(cspsvx,CSPSVX) #define LAPACK_zspsvx LAPACK_GLOBAL(zspsvx,ZSPSVX) #define LAPACK_chpsv LAPACK_GLOBAL(chpsv,CHPSV) #define LAPACK_zhpsv LAPACK_GLOBAL(zhpsv,ZHPSV) #define LAPACK_chpsvx LAPACK_GLOBAL(chpsvx,CHPSVX) #define LAPACK_zhpsvx LAPACK_GLOBAL(zhpsvx,ZHPSVX) #define LAPACK_sgeqrf LAPACK_GLOBAL(sgeqrf,SGEQRF) #define LAPACK_dgeqrf LAPACK_GLOBAL(dgeqrf,DGEQRF) #define LAPACK_cgeqrf LAPACK_GLOBAL(cgeqrf,CGEQRF) #define LAPACK_zgeqrf LAPACK_GLOBAL(zgeqrf,ZGEQRF) #define LAPACK_sgeqpf LAPACK_GLOBAL(sgeqpf,SGEQPF) #define LAPACK_dgeqpf LAPACK_GLOBAL(dgeqpf,DGEQPF) #define LAPACK_cgeqpf LAPACK_GLOBAL(cgeqpf,CGEQPF) #define LAPACK_zgeqpf LAPACK_GLOBAL(zgeqpf,ZGEQPF) #define LAPACK_sgeqp3 LAPACK_GLOBAL(sgeqp3,SGEQP3) #define LAPACK_dgeqp3 LAPACK_GLOBAL(dgeqp3,DGEQP3) #define LAPACK_cgeqp3 LAPACK_GLOBAL(cgeqp3,CGEQP3) #define LAPACK_zgeqp3 LAPACK_GLOBAL(zgeqp3,ZGEQP3) #define LAPACK_sorgqr LAPACK_GLOBAL(sorgqr,SORGQR) #define LAPACK_dorgqr LAPACK_GLOBAL(dorgqr,DORGQR) #define LAPACK_sormqr LAPACK_GLOBAL(sormqr,SORMQR) #define LAPACK_dormqr LAPACK_GLOBAL(dormqr,DORMQR) #define LAPACK_cungqr LAPACK_GLOBAL(cungqr,CUNGQR) #define LAPACK_zungqr LAPACK_GLOBAL(zungqr,ZUNGQR) #define LAPACK_cunmqr LAPACK_GLOBAL(cunmqr,CUNMQR) #define LAPACK_zunmqr LAPACK_GLOBAL(zunmqr,ZUNMQR) #define LAPACK_sgelqf LAPACK_GLOBAL(sgelqf,SGELQF) #define LAPACK_dgelqf LAPACK_GLOBAL(dgelqf,DGELQF) #define LAPACK_cgelqf LAPACK_GLOBAL(cgelqf,CGELQF) #define LAPACK_zgelqf LAPACK_GLOBAL(zgelqf,ZGELQF) #define LAPACK_sorglq LAPACK_GLOBAL(sorglq,SORGLQ) #define LAPACK_dorglq LAPACK_GLOBAL(dorglq,DORGLQ) #define LAPACK_sormlq LAPACK_GLOBAL(sormlq,SORMLQ) #define LAPACK_dormlq LAPACK_GLOBAL(dormlq,DORMLQ) #define LAPACK_cunglq LAPACK_GLOBAL(cunglq,CUNGLQ) #define LAPACK_zunglq LAPACK_GLOBAL(zunglq,ZUNGLQ) #define LAPACK_cunmlq LAPACK_GLOBAL(cunmlq,CUNMLQ) #define LAPACK_zunmlq LAPACK_GLOBAL(zunmlq,ZUNMLQ) #define LAPACK_sgeqlf LAPACK_GLOBAL(sgeqlf,SGEQLF) #define LAPACK_dgeqlf LAPACK_GLOBAL(dgeqlf,DGEQLF) #define LAPACK_cgeqlf LAPACK_GLOBAL(cgeqlf,CGEQLF) #define LAPACK_zgeqlf LAPACK_GLOBAL(zgeqlf,ZGEQLF) #define LAPACK_sorgql LAPACK_GLOBAL(sorgql,SORGQL) #define LAPACK_dorgql LAPACK_GLOBAL(dorgql,DORGQL) #define LAPACK_cungql LAPACK_GLOBAL(cungql,CUNGQL) #define LAPACK_zungql LAPACK_GLOBAL(zungql,ZUNGQL) #define LAPACK_sormql LAPACK_GLOBAL(sormql,SORMQL) #define LAPACK_dormql LAPACK_GLOBAL(dormql,DORMQL) #define LAPACK_cunmql LAPACK_GLOBAL(cunmql,CUNMQL) #define LAPACK_zunmql LAPACK_GLOBAL(zunmql,ZUNMQL) #define LAPACK_sgerqf LAPACK_GLOBAL(sgerqf,SGERQF) #define LAPACK_dgerqf LAPACK_GLOBAL(dgerqf,DGERQF) #define LAPACK_cgerqf LAPACK_GLOBAL(cgerqf,CGERQF) #define LAPACK_zgerqf LAPACK_GLOBAL(zgerqf,ZGERQF) #define LAPACK_sorgrq LAPACK_GLOBAL(sorgrq,SORGRQ) #define LAPACK_dorgrq LAPACK_GLOBAL(dorgrq,DORGRQ) #define LAPACK_cungrq LAPACK_GLOBAL(cungrq,CUNGRQ) #define LAPACK_zungrq LAPACK_GLOBAL(zungrq,ZUNGRQ) #define LAPACK_sormrq LAPACK_GLOBAL(sormrq,SORMRQ) #define LAPACK_dormrq LAPACK_GLOBAL(dormrq,DORMRQ) #define LAPACK_cunmrq LAPACK_GLOBAL(cunmrq,CUNMRQ) #define LAPACK_zunmrq LAPACK_GLOBAL(zunmrq,ZUNMRQ) #define LAPACK_stzrzf LAPACK_GLOBAL(stzrzf,STZRZF) #define LAPACK_dtzrzf LAPACK_GLOBAL(dtzrzf,DTZRZF) #define LAPACK_ctzrzf LAPACK_GLOBAL(ctzrzf,CTZRZF) #define LAPACK_ztzrzf LAPACK_GLOBAL(ztzrzf,ZTZRZF) #define LAPACK_sormrz LAPACK_GLOBAL(sormrz,SORMRZ) #define LAPACK_dormrz LAPACK_GLOBAL(dormrz,DORMRZ) #define LAPACK_cunmrz LAPACK_GLOBAL(cunmrz,CUNMRZ) #define LAPACK_zunmrz LAPACK_GLOBAL(zunmrz,ZUNMRZ) #define LAPACK_sggqrf LAPACK_GLOBAL(sggqrf,SGGQRF) #define LAPACK_dggqrf LAPACK_GLOBAL(dggqrf,DGGQRF) #define LAPACK_cggqrf LAPACK_GLOBAL(cggqrf,CGGQRF) #define LAPACK_zggqrf LAPACK_GLOBAL(zggqrf,ZGGQRF) #define LAPACK_sggrqf LAPACK_GLOBAL(sggrqf,SGGRQF) #define LAPACK_dggrqf LAPACK_GLOBAL(dggrqf,DGGRQF) #define LAPACK_cggrqf LAPACK_GLOBAL(cggrqf,CGGRQF) #define LAPACK_zggrqf LAPACK_GLOBAL(zggrqf,ZGGRQF) #define LAPACK_sgebrd LAPACK_GLOBAL(sgebrd,SGEBRD) #define LAPACK_dgebrd LAPACK_GLOBAL(dgebrd,DGEBRD) #define LAPACK_cgebrd LAPACK_GLOBAL(cgebrd,CGEBRD) #define LAPACK_zgebrd LAPACK_GLOBAL(zgebrd,ZGEBRD) #define LAPACK_sgbbrd LAPACK_GLOBAL(sgbbrd,SGBBRD) #define LAPACK_dgbbrd LAPACK_GLOBAL(dgbbrd,DGBBRD) #define LAPACK_cgbbrd LAPACK_GLOBAL(cgbbrd,CGBBRD) #define LAPACK_zgbbrd LAPACK_GLOBAL(zgbbrd,ZGBBRD) #define LAPACK_sorgbr LAPACK_GLOBAL(sorgbr,SORGBR) #define LAPACK_dorgbr LAPACK_GLOBAL(dorgbr,DORGBR) #define LAPACK_sormbr LAPACK_GLOBAL(sormbr,SORMBR) #define LAPACK_dormbr LAPACK_GLOBAL(dormbr,DORMBR) #define LAPACK_cungbr LAPACK_GLOBAL(cungbr,CUNGBR) #define LAPACK_zungbr LAPACK_GLOBAL(zungbr,ZUNGBR) #define LAPACK_cunmbr LAPACK_GLOBAL(cunmbr,CUNMBR) #define LAPACK_zunmbr LAPACK_GLOBAL(zunmbr,ZUNMBR) #define LAPACK_sbdsqr LAPACK_GLOBAL(sbdsqr,SBDSQR) #define LAPACK_dbdsqr LAPACK_GLOBAL(dbdsqr,DBDSQR) #define LAPACK_cbdsqr LAPACK_GLOBAL(cbdsqr,CBDSQR) #define LAPACK_zbdsqr LAPACK_GLOBAL(zbdsqr,ZBDSQR) #define LAPACK_sbdsdc LAPACK_GLOBAL(sbdsdc,SBDSDC) #define LAPACK_dbdsdc LAPACK_GLOBAL(dbdsdc,DBDSDC) #define LAPACK_ssytrd LAPACK_GLOBAL(ssytrd,SSYTRD) #define LAPACK_dsytrd LAPACK_GLOBAL(dsytrd,DSYTRD) #define LAPACK_sorgtr LAPACK_GLOBAL(sorgtr,SORGTR) #define LAPACK_dorgtr LAPACK_GLOBAL(dorgtr,DORGTR) #define LAPACK_sormtr LAPACK_GLOBAL(sormtr,SORMTR) #define LAPACK_dormtr LAPACK_GLOBAL(dormtr,DORMTR) #define LAPACK_chetrd LAPACK_GLOBAL(chetrd,CHETRD) #define LAPACK_zhetrd LAPACK_GLOBAL(zhetrd,ZHETRD) #define LAPACK_cungtr LAPACK_GLOBAL(cungtr,CUNGTR) #define LAPACK_zungtr LAPACK_GLOBAL(zungtr,ZUNGTR) #define LAPACK_cunmtr LAPACK_GLOBAL(cunmtr,CUNMTR) #define LAPACK_zunmtr LAPACK_GLOBAL(zunmtr,ZUNMTR) #define LAPACK_ssptrd LAPACK_GLOBAL(ssptrd,SSPTRD) #define LAPACK_dsptrd LAPACK_GLOBAL(dsptrd,DSPTRD) #define LAPACK_sopgtr LAPACK_GLOBAL(sopgtr,SOPGTR) #define LAPACK_dopgtr LAPACK_GLOBAL(dopgtr,DOPGTR) #define LAPACK_sopmtr LAPACK_GLOBAL(sopmtr,SOPMTR) #define LAPACK_dopmtr LAPACK_GLOBAL(dopmtr,DOPMTR) #define LAPACK_chptrd LAPACK_GLOBAL(chptrd,CHPTRD) #define LAPACK_zhptrd LAPACK_GLOBAL(zhptrd,ZHPTRD) #define LAPACK_cupgtr LAPACK_GLOBAL(cupgtr,CUPGTR) #define LAPACK_zupgtr LAPACK_GLOBAL(zupgtr,ZUPGTR) #define LAPACK_cupmtr LAPACK_GLOBAL(cupmtr,CUPMTR) #define LAPACK_zupmtr LAPACK_GLOBAL(zupmtr,ZUPMTR) #define LAPACK_ssbtrd LAPACK_GLOBAL(ssbtrd,SSBTRD) #define LAPACK_dsbtrd LAPACK_GLOBAL(dsbtrd,DSBTRD) #define LAPACK_chbtrd LAPACK_GLOBAL(chbtrd,CHBTRD) #define LAPACK_zhbtrd LAPACK_GLOBAL(zhbtrd,ZHBTRD) #define LAPACK_ssterf LAPACK_GLOBAL(ssterf,SSTERF) #define LAPACK_dsterf LAPACK_GLOBAL(dsterf,DSTERF) #define LAPACK_ssteqr LAPACK_GLOBAL(ssteqr,SSTEQR) #define LAPACK_dsteqr LAPACK_GLOBAL(dsteqr,DSTEQR) #define LAPACK_csteqr LAPACK_GLOBAL(csteqr,CSTEQR) #define LAPACK_zsteqr LAPACK_GLOBAL(zsteqr,ZSTEQR) #define LAPACK_sstemr LAPACK_GLOBAL(sstemr,SSTEMR) #define LAPACK_dstemr LAPACK_GLOBAL(dstemr,DSTEMR) #define LAPACK_cstemr LAPACK_GLOBAL(cstemr,CSTEMR) #define LAPACK_zstemr LAPACK_GLOBAL(zstemr,ZSTEMR) #define LAPACK_sstedc LAPACK_GLOBAL(sstedc,SSTEDC) #define LAPACK_dstedc LAPACK_GLOBAL(dstedc,DSTEDC) #define LAPACK_cstedc LAPACK_GLOBAL(cstedc,CSTEDC) #define LAPACK_zstedc LAPACK_GLOBAL(zstedc,ZSTEDC) #define LAPACK_sstegr LAPACK_GLOBAL(sstegr,SSTEGR) #define LAPACK_dstegr LAPACK_GLOBAL(dstegr,DSTEGR) #define LAPACK_cstegr LAPACK_GLOBAL(cstegr,CSTEGR) #define LAPACK_zstegr LAPACK_GLOBAL(zstegr,ZSTEGR) #define LAPACK_spteqr LAPACK_GLOBAL(spteqr,SPTEQR) #define LAPACK_dpteqr LAPACK_GLOBAL(dpteqr,DPTEQR) #define LAPACK_cpteqr LAPACK_GLOBAL(cpteqr,CPTEQR) #define LAPACK_zpteqr LAPACK_GLOBAL(zpteqr,ZPTEQR) #define LAPACK_sstebz LAPACK_GLOBAL(sstebz,SSTEBZ) #define LAPACK_dstebz LAPACK_GLOBAL(dstebz,DSTEBZ) #define LAPACK_sstein LAPACK_GLOBAL(sstein,SSTEIN) #define LAPACK_dstein LAPACK_GLOBAL(dstein,DSTEIN) #define LAPACK_cstein LAPACK_GLOBAL(cstein,CSTEIN) #define LAPACK_zstein LAPACK_GLOBAL(zstein,ZSTEIN) #define LAPACK_sdisna LAPACK_GLOBAL(sdisna,SDISNA) #define LAPACK_ddisna LAPACK_GLOBAL(ddisna,DDISNA) #define LAPACK_ssygst LAPACK_GLOBAL(ssygst,SSYGST) #define LAPACK_dsygst LAPACK_GLOBAL(dsygst,DSYGST) #define LAPACK_chegst LAPACK_GLOBAL(chegst,CHEGST) #define LAPACK_zhegst LAPACK_GLOBAL(zhegst,ZHEGST) #define LAPACK_sspgst LAPACK_GLOBAL(sspgst,SSPGST) #define LAPACK_dspgst LAPACK_GLOBAL(dspgst,DSPGST) #define LAPACK_chpgst LAPACK_GLOBAL(chpgst,CHPGST) #define LAPACK_zhpgst LAPACK_GLOBAL(zhpgst,ZHPGST) #define LAPACK_ssbgst LAPACK_GLOBAL(ssbgst,SSBGST) #define LAPACK_dsbgst LAPACK_GLOBAL(dsbgst,DSBGST) #define LAPACK_chbgst LAPACK_GLOBAL(chbgst,CHBGST) #define LAPACK_zhbgst LAPACK_GLOBAL(zhbgst,ZHBGST) #define LAPACK_spbstf LAPACK_GLOBAL(spbstf,SPBSTF) #define LAPACK_dpbstf LAPACK_GLOBAL(dpbstf,DPBSTF) #define LAPACK_cpbstf LAPACK_GLOBAL(cpbstf,CPBSTF) #define LAPACK_zpbstf LAPACK_GLOBAL(zpbstf,ZPBSTF) #define LAPACK_sgehrd LAPACK_GLOBAL(sgehrd,SGEHRD) #define LAPACK_dgehrd LAPACK_GLOBAL(dgehrd,DGEHRD) #define LAPACK_cgehrd LAPACK_GLOBAL(cgehrd,CGEHRD) #define LAPACK_zgehrd LAPACK_GLOBAL(zgehrd,ZGEHRD) #define LAPACK_sorghr LAPACK_GLOBAL(sorghr,SORGHR) #define LAPACK_dorghr LAPACK_GLOBAL(dorghr,DORGHR) #define LAPACK_sormhr LAPACK_GLOBAL(sormhr,SORMHR) #define LAPACK_dormhr LAPACK_GLOBAL(dormhr,DORMHR) #define LAPACK_cunghr LAPACK_GLOBAL(cunghr,CUNGHR) #define LAPACK_zunghr LAPACK_GLOBAL(zunghr,ZUNGHR) #define LAPACK_cunmhr LAPACK_GLOBAL(cunmhr,CUNMHR) #define LAPACK_zunmhr LAPACK_GLOBAL(zunmhr,ZUNMHR) #define LAPACK_sgebal LAPACK_GLOBAL(sgebal,SGEBAL) #define LAPACK_dgebal LAPACK_GLOBAL(dgebal,DGEBAL) #define LAPACK_cgebal LAPACK_GLOBAL(cgebal,CGEBAL) #define LAPACK_zgebal LAPACK_GLOBAL(zgebal,ZGEBAL) #define LAPACK_sgebak LAPACK_GLOBAL(sgebak,SGEBAK) #define LAPACK_dgebak LAPACK_GLOBAL(dgebak,DGEBAK) #define LAPACK_cgebak LAPACK_GLOBAL(cgebak,CGEBAK) #define LAPACK_zgebak LAPACK_GLOBAL(zgebak,ZGEBAK) #define LAPACK_shseqr LAPACK_GLOBAL(shseqr,SHSEQR) #define LAPACK_dhseqr LAPACK_GLOBAL(dhseqr,DHSEQR) #define LAPACK_chseqr LAPACK_GLOBAL(chseqr,CHSEQR) #define LAPACK_zhseqr LAPACK_GLOBAL(zhseqr,ZHSEQR) #define LAPACK_shsein LAPACK_GLOBAL(shsein,SHSEIN) #define LAPACK_dhsein LAPACK_GLOBAL(dhsein,DHSEIN) #define LAPACK_chsein LAPACK_GLOBAL(chsein,CHSEIN) #define LAPACK_zhsein LAPACK_GLOBAL(zhsein,ZHSEIN) #define LAPACK_strevc LAPACK_GLOBAL(strevc,STREVC) #define LAPACK_dtrevc LAPACK_GLOBAL(dtrevc,DTREVC) #define LAPACK_ctrevc LAPACK_GLOBAL(ctrevc,CTREVC) #define LAPACK_ztrevc LAPACK_GLOBAL(ztrevc,ZTREVC) #define LAPACK_strsna LAPACK_GLOBAL(strsna,STRSNA) #define LAPACK_dtrsna LAPACK_GLOBAL(dtrsna,DTRSNA) #define LAPACK_ctrsna LAPACK_GLOBAL(ctrsna,CTRSNA) #define LAPACK_ztrsna LAPACK_GLOBAL(ztrsna,ZTRSNA) #define LAPACK_strexc LAPACK_GLOBAL(strexc,STREXC) #define LAPACK_dtrexc LAPACK_GLOBAL(dtrexc,DTREXC) #define LAPACK_ctrexc LAPACK_GLOBAL(ctrexc,CTREXC) #define LAPACK_ztrexc LAPACK_GLOBAL(ztrexc,ZTREXC) #define LAPACK_strsen LAPACK_GLOBAL(strsen,STRSEN) #define LAPACK_dtrsen LAPACK_GLOBAL(dtrsen,DTRSEN) #define LAPACK_ctrsen LAPACK_GLOBAL(ctrsen,CTRSEN) #define LAPACK_ztrsen LAPACK_GLOBAL(ztrsen,ZTRSEN) #define LAPACK_strsyl LAPACK_GLOBAL(strsyl,STRSYL) #define LAPACK_dtrsyl LAPACK_GLOBAL(dtrsyl,DTRSYL) #define LAPACK_ctrsyl LAPACK_GLOBAL(ctrsyl,CTRSYL) #define LAPACK_ztrsyl LAPACK_GLOBAL(ztrsyl,ZTRSYL) #define LAPACK_sgghrd LAPACK_GLOBAL(sgghrd,SGGHRD) #define LAPACK_dgghrd LAPACK_GLOBAL(dgghrd,DGGHRD) #define LAPACK_cgghrd LAPACK_GLOBAL(cgghrd,CGGHRD) #define LAPACK_zgghrd LAPACK_GLOBAL(zgghrd,ZGGHRD) #define LAPACK_sggbal LAPACK_GLOBAL(sggbal,SGGBAL) #define LAPACK_dggbal LAPACK_GLOBAL(dggbal,DGGBAL) #define LAPACK_cggbal LAPACK_GLOBAL(cggbal,CGGBAL) #define LAPACK_zggbal LAPACK_GLOBAL(zggbal,ZGGBAL) #define LAPACK_sggbak LAPACK_GLOBAL(sggbak,SGGBAK) #define LAPACK_dggbak LAPACK_GLOBAL(dggbak,DGGBAK) #define LAPACK_cggbak LAPACK_GLOBAL(cggbak,CGGBAK) #define LAPACK_zggbak LAPACK_GLOBAL(zggbak,ZGGBAK) #define LAPACK_shgeqz LAPACK_GLOBAL(shgeqz,SHGEQZ) #define LAPACK_dhgeqz LAPACK_GLOBAL(dhgeqz,DHGEQZ) #define LAPACK_chgeqz LAPACK_GLOBAL(chgeqz,CHGEQZ) #define LAPACK_zhgeqz LAPACK_GLOBAL(zhgeqz,ZHGEQZ) #define LAPACK_stgevc LAPACK_GLOBAL(stgevc,STGEVC) #define LAPACK_dtgevc LAPACK_GLOBAL(dtgevc,DTGEVC) #define LAPACK_ctgevc LAPACK_GLOBAL(ctgevc,CTGEVC) #define LAPACK_ztgevc LAPACK_GLOBAL(ztgevc,ZTGEVC) #define LAPACK_stgexc LAPACK_GLOBAL(stgexc,STGEXC) #define LAPACK_dtgexc LAPACK_GLOBAL(dtgexc,DTGEXC) #define LAPACK_ctgexc LAPACK_GLOBAL(ctgexc,CTGEXC) #define LAPACK_ztgexc LAPACK_GLOBAL(ztgexc,ZTGEXC) #define LAPACK_stgsen LAPACK_GLOBAL(stgsen,STGSEN) #define LAPACK_dtgsen LAPACK_GLOBAL(dtgsen,DTGSEN) #define LAPACK_ctgsen LAPACK_GLOBAL(ctgsen,CTGSEN) #define LAPACK_ztgsen LAPACK_GLOBAL(ztgsen,ZTGSEN) #define LAPACK_stgsyl LAPACK_GLOBAL(stgsyl,STGSYL) #define LAPACK_dtgsyl LAPACK_GLOBAL(dtgsyl,DTGSYL) #define LAPACK_ctgsyl LAPACK_GLOBAL(ctgsyl,CTGSYL) #define LAPACK_ztgsyl LAPACK_GLOBAL(ztgsyl,ZTGSYL) #define LAPACK_stgsna LAPACK_GLOBAL(stgsna,STGSNA) #define LAPACK_dtgsna LAPACK_GLOBAL(dtgsna,DTGSNA) #define LAPACK_ctgsna LAPACK_GLOBAL(ctgsna,CTGSNA) #define LAPACK_ztgsna LAPACK_GLOBAL(ztgsna,ZTGSNA) #define LAPACK_sggsvp LAPACK_GLOBAL(sggsvp,SGGSVP) #define LAPACK_dggsvp LAPACK_GLOBAL(dggsvp,DGGSVP) #define LAPACK_cggsvp LAPACK_GLOBAL(cggsvp,CGGSVP) #define LAPACK_zggsvp LAPACK_GLOBAL(zggsvp,ZGGSVP) #define LAPACK_stgsja LAPACK_GLOBAL(stgsja,STGSJA) #define LAPACK_dtgsja LAPACK_GLOBAL(dtgsja,DTGSJA) #define LAPACK_ctgsja LAPACK_GLOBAL(ctgsja,CTGSJA) #define LAPACK_ztgsja LAPACK_GLOBAL(ztgsja,ZTGSJA) #define LAPACK_sgels LAPACK_GLOBAL(sgels,SGELS) #define LAPACK_dgels LAPACK_GLOBAL(dgels,DGELS) #define LAPACK_cgels LAPACK_GLOBAL(cgels,CGELS) #define LAPACK_zgels LAPACK_GLOBAL(zgels,ZGELS) #define LAPACK_sgelsy LAPACK_GLOBAL(sgelsy,SGELSY) #define LAPACK_dgelsy LAPACK_GLOBAL(dgelsy,DGELSY) #define LAPACK_cgelsy LAPACK_GLOBAL(cgelsy,CGELSY) #define LAPACK_zgelsy LAPACK_GLOBAL(zgelsy,ZGELSY) #define LAPACK_sgelss LAPACK_GLOBAL(sgelss,SGELSS) #define LAPACK_dgelss LAPACK_GLOBAL(dgelss,DGELSS) #define LAPACK_cgelss LAPACK_GLOBAL(cgelss,CGELSS) #define LAPACK_zgelss LAPACK_GLOBAL(zgelss,ZGELSS) #define LAPACK_sgelsd LAPACK_GLOBAL(sgelsd,SGELSD) #define LAPACK_dgelsd LAPACK_GLOBAL(dgelsd,DGELSD) #define LAPACK_cgelsd LAPACK_GLOBAL(cgelsd,CGELSD) #define LAPACK_zgelsd LAPACK_GLOBAL(zgelsd,ZGELSD) #define LAPACK_sgglse LAPACK_GLOBAL(sgglse,SGGLSE) #define LAPACK_dgglse LAPACK_GLOBAL(dgglse,DGGLSE) #define LAPACK_cgglse LAPACK_GLOBAL(cgglse,CGGLSE) #define LAPACK_zgglse LAPACK_GLOBAL(zgglse,ZGGLSE) #define LAPACK_sggglm LAPACK_GLOBAL(sggglm,SGGGLM) #define LAPACK_dggglm LAPACK_GLOBAL(dggglm,DGGGLM) #define LAPACK_cggglm LAPACK_GLOBAL(cggglm,CGGGLM) #define LAPACK_zggglm LAPACK_GLOBAL(zggglm,ZGGGLM) #define LAPACK_ssyev LAPACK_GLOBAL(ssyev,SSYEV) #define LAPACK_dsyev LAPACK_GLOBAL(dsyev,DSYEV) #define LAPACK_cheev LAPACK_GLOBAL(cheev,CHEEV) #define LAPACK_zheev LAPACK_GLOBAL(zheev,ZHEEV) #define LAPACK_ssyevd LAPACK_GLOBAL(ssyevd,SSYEVD) #define LAPACK_dsyevd LAPACK_GLOBAL(dsyevd,DSYEVD) #define LAPACK_cheevd LAPACK_GLOBAL(cheevd,CHEEVD) #define LAPACK_zheevd LAPACK_GLOBAL(zheevd,ZHEEVD) #define LAPACK_ssyevx LAPACK_GLOBAL(ssyevx,SSYEVX) #define LAPACK_dsyevx LAPACK_GLOBAL(dsyevx,DSYEVX) #define LAPACK_cheevx LAPACK_GLOBAL(cheevx,CHEEVX) #define LAPACK_zheevx LAPACK_GLOBAL(zheevx,ZHEEVX) #define LAPACK_ssyevr LAPACK_GLOBAL(ssyevr,SSYEVR) #define LAPACK_dsyevr LAPACK_GLOBAL(dsyevr,DSYEVR) #define LAPACK_cheevr LAPACK_GLOBAL(cheevr,CHEEVR) #define LAPACK_zheevr LAPACK_GLOBAL(zheevr,ZHEEVR) #define LAPACK_sspev LAPACK_GLOBAL(sspev,SSPEV) #define LAPACK_dspev LAPACK_GLOBAL(dspev,DSPEV) #define LAPACK_chpev LAPACK_GLOBAL(chpev,CHPEV) #define LAPACK_zhpev LAPACK_GLOBAL(zhpev,ZHPEV) #define LAPACK_sspevd LAPACK_GLOBAL(sspevd,SSPEVD) #define LAPACK_dspevd LAPACK_GLOBAL(dspevd,DSPEVD) #define LAPACK_chpevd LAPACK_GLOBAL(chpevd,CHPEVD) #define LAPACK_zhpevd LAPACK_GLOBAL(zhpevd,ZHPEVD) #define LAPACK_sspevx LAPACK_GLOBAL(sspevx,SSPEVX) #define LAPACK_dspevx LAPACK_GLOBAL(dspevx,DSPEVX) #define LAPACK_chpevx LAPACK_GLOBAL(chpevx,CHPEVX) #define LAPACK_zhpevx LAPACK_GLOBAL(zhpevx,ZHPEVX) #define LAPACK_ssbev LAPACK_GLOBAL(ssbev,SSBEV) #define LAPACK_dsbev LAPACK_GLOBAL(dsbev,DSBEV) #define LAPACK_chbev LAPACK_GLOBAL(chbev,CHBEV) #define LAPACK_zhbev LAPACK_GLOBAL(zhbev,ZHBEV) #define LAPACK_ssbevd LAPACK_GLOBAL(ssbevd,SSBEVD) #define LAPACK_dsbevd LAPACK_GLOBAL(dsbevd,DSBEVD) #define LAPACK_chbevd LAPACK_GLOBAL(chbevd,CHBEVD) #define LAPACK_zhbevd LAPACK_GLOBAL(zhbevd,ZHBEVD) #define LAPACK_ssbevx LAPACK_GLOBAL(ssbevx,SSBEVX) #define LAPACK_dsbevx LAPACK_GLOBAL(dsbevx,DSBEVX) #define LAPACK_chbevx LAPACK_GLOBAL(chbevx,CHBEVX) #define LAPACK_zhbevx LAPACK_GLOBAL(zhbevx,ZHBEVX) #define LAPACK_sstev LAPACK_GLOBAL(sstev,SSTEV) #define LAPACK_dstev LAPACK_GLOBAL(dstev,DSTEV) #define LAPACK_sstevd LAPACK_GLOBAL(sstevd,SSTEVD) #define LAPACK_dstevd LAPACK_GLOBAL(dstevd,DSTEVD) #define LAPACK_sstevx LAPACK_GLOBAL(sstevx,SSTEVX) #define LAPACK_dstevx LAPACK_GLOBAL(dstevx,DSTEVX) #define LAPACK_sstevr LAPACK_GLOBAL(sstevr,SSTEVR) #define LAPACK_dstevr LAPACK_GLOBAL(dstevr,DSTEVR) #define LAPACK_sgees LAPACK_GLOBAL(sgees,SGEES) #define LAPACK_dgees LAPACK_GLOBAL(dgees,DGEES) #define LAPACK_cgees LAPACK_GLOBAL(cgees,CGEES) #define LAPACK_zgees LAPACK_GLOBAL(zgees,ZGEES) #define LAPACK_sgeesx LAPACK_GLOBAL(sgeesx,SGEESX) #define LAPACK_dgeesx LAPACK_GLOBAL(dgeesx,DGEESX) #define LAPACK_cgeesx LAPACK_GLOBAL(cgeesx,CGEESX) #define LAPACK_zgeesx LAPACK_GLOBAL(zgeesx,ZGEESX) #define LAPACK_sgeev LAPACK_GLOBAL(sgeev,SGEEV) #define LAPACK_dgeev LAPACK_GLOBAL(dgeev,DGEEV) #define LAPACK_cgeev LAPACK_GLOBAL(cgeev,CGEEV) #define LAPACK_zgeev LAPACK_GLOBAL(zgeev,ZGEEV) #define LAPACK_sgeevx LAPACK_GLOBAL(sgeevx,SGEEVX) #define LAPACK_dgeevx LAPACK_GLOBAL(dgeevx,DGEEVX) #define LAPACK_cgeevx LAPACK_GLOBAL(cgeevx,CGEEVX) #define LAPACK_zgeevx LAPACK_GLOBAL(zgeevx,ZGEEVX) #define LAPACK_sgesvd LAPACK_GLOBAL(sgesvd,SGESVD) #define LAPACK_dgesvd LAPACK_GLOBAL(dgesvd,DGESVD) #define LAPACK_cgesvd LAPACK_GLOBAL(cgesvd,CGESVD) #define LAPACK_zgesvd LAPACK_GLOBAL(zgesvd,ZGESVD) #define LAPACK_sgesdd LAPACK_GLOBAL(sgesdd,SGESDD) #define LAPACK_dgesdd LAPACK_GLOBAL(dgesdd,DGESDD) #define LAPACK_cgesdd LAPACK_GLOBAL(cgesdd,CGESDD) #define LAPACK_zgesdd LAPACK_GLOBAL(zgesdd,ZGESDD) #define LAPACK_dgejsv LAPACK_GLOBAL(dgejsv,DGEJSV) #define LAPACK_sgejsv LAPACK_GLOBAL(sgejsv,SGEJSV) #define LAPACK_dgesvj LAPACK_GLOBAL(dgesvj,DGESVJ) #define LAPACK_sgesvj LAPACK_GLOBAL(sgesvj,SGESVJ) #define LAPACK_sggsvd LAPACK_GLOBAL(sggsvd,SGGSVD) #define LAPACK_dggsvd LAPACK_GLOBAL(dggsvd,DGGSVD) #define LAPACK_cggsvd LAPACK_GLOBAL(cggsvd,CGGSVD) #define LAPACK_zggsvd LAPACK_GLOBAL(zggsvd,ZGGSVD) #define LAPACK_ssygv LAPACK_GLOBAL(ssygv,SSYGV) #define LAPACK_dsygv LAPACK_GLOBAL(dsygv,DSYGV) #define LAPACK_chegv LAPACK_GLOBAL(chegv,CHEGV) #define LAPACK_zhegv LAPACK_GLOBAL(zhegv,ZHEGV) #define LAPACK_ssygvd LAPACK_GLOBAL(ssygvd,SSYGVD) #define LAPACK_dsygvd LAPACK_GLOBAL(dsygvd,DSYGVD) #define LAPACK_chegvd LAPACK_GLOBAL(chegvd,CHEGVD) #define LAPACK_zhegvd LAPACK_GLOBAL(zhegvd,ZHEGVD) #define LAPACK_ssygvx LAPACK_GLOBAL(ssygvx,SSYGVX) #define LAPACK_dsygvx LAPACK_GLOBAL(dsygvx,DSYGVX) #define LAPACK_chegvx LAPACK_GLOBAL(chegvx,CHEGVX) #define LAPACK_zhegvx LAPACK_GLOBAL(zhegvx,ZHEGVX) #define LAPACK_sspgv LAPACK_GLOBAL(sspgv,SSPGV) #define LAPACK_dspgv LAPACK_GLOBAL(dspgv,DSPGV) #define LAPACK_chpgv LAPACK_GLOBAL(chpgv,CHPGV) #define LAPACK_zhpgv LAPACK_GLOBAL(zhpgv,ZHPGV) #define LAPACK_sspgvd LAPACK_GLOBAL(sspgvd,SSPGVD) #define LAPACK_dspgvd LAPACK_GLOBAL(dspgvd,DSPGVD) #define LAPACK_chpgvd LAPACK_GLOBAL(chpgvd,CHPGVD) #define LAPACK_zhpgvd LAPACK_GLOBAL(zhpgvd,ZHPGVD) #define LAPACK_sspgvx LAPACK_GLOBAL(sspgvx,SSPGVX) #define LAPACK_dspgvx LAPACK_GLOBAL(dspgvx,DSPGVX) #define LAPACK_chpgvx LAPACK_GLOBAL(chpgvx,CHPGVX) #define LAPACK_zhpgvx LAPACK_GLOBAL(zhpgvx,ZHPGVX) #define LAPACK_ssbgv LAPACK_GLOBAL(ssbgv,SSBGV) #define LAPACK_dsbgv LAPACK_GLOBAL(dsbgv,DSBGV) #define LAPACK_chbgv LAPACK_GLOBAL(chbgv,CHBGV) #define LAPACK_zhbgv LAPACK_GLOBAL(zhbgv,ZHBGV) #define LAPACK_ssbgvd LAPACK_GLOBAL(ssbgvd,SSBGVD) #define LAPACK_dsbgvd LAPACK_GLOBAL(dsbgvd,DSBGVD) #define LAPACK_chbgvd LAPACK_GLOBAL(chbgvd,CHBGVD) #define LAPACK_zhbgvd LAPACK_GLOBAL(zhbgvd,ZHBGVD) #define LAPACK_ssbgvx LAPACK_GLOBAL(ssbgvx,SSBGVX) #define LAPACK_dsbgvx LAPACK_GLOBAL(dsbgvx,DSBGVX) #define LAPACK_chbgvx LAPACK_GLOBAL(chbgvx,CHBGVX) #define LAPACK_zhbgvx LAPACK_GLOBAL(zhbgvx,ZHBGVX) #define LAPACK_sgges LAPACK_GLOBAL(sgges,SGGES) #define LAPACK_dgges LAPACK_GLOBAL(dgges,DGGES) #define LAPACK_cgges LAPACK_GLOBAL(cgges,CGGES) #define LAPACK_zgges LAPACK_GLOBAL(zgges,ZGGES) #define LAPACK_sggesx LAPACK_GLOBAL(sggesx,SGGESX) #define LAPACK_dggesx LAPACK_GLOBAL(dggesx,DGGESX) #define LAPACK_cggesx LAPACK_GLOBAL(cggesx,CGGESX) #define LAPACK_zggesx LAPACK_GLOBAL(zggesx,ZGGESX) #define LAPACK_sggev LAPACK_GLOBAL(sggev,SGGEV) #define LAPACK_dggev LAPACK_GLOBAL(dggev,DGGEV) #define LAPACK_cggev LAPACK_GLOBAL(cggev,CGGEV) #define LAPACK_zggev LAPACK_GLOBAL(zggev,ZGGEV) #define LAPACK_sggevx LAPACK_GLOBAL(sggevx,SGGEVX) #define LAPACK_dggevx LAPACK_GLOBAL(dggevx,DGGEVX) #define LAPACK_cggevx LAPACK_GLOBAL(cggevx,CGGEVX) #define LAPACK_zggevx LAPACK_GLOBAL(zggevx,ZGGEVX) #define LAPACK_dsfrk LAPACK_GLOBAL(dsfrk,DSFRK) #define LAPACK_ssfrk LAPACK_GLOBAL(ssfrk,SSFRK) #define LAPACK_zhfrk LAPACK_GLOBAL(zhfrk,ZHFRK) #define LAPACK_chfrk LAPACK_GLOBAL(chfrk,CHFRK) #define LAPACK_dtfsm LAPACK_GLOBAL(dtfsm,DTFSM) #define LAPACK_stfsm LAPACK_GLOBAL(stfsm,STFSM) #define LAPACK_ztfsm LAPACK_GLOBAL(ztfsm,ZTFSM) #define LAPACK_ctfsm LAPACK_GLOBAL(ctfsm,CTFSM) #define LAPACK_dtfttp LAPACK_GLOBAL(dtfttp,DTFTTP) #define LAPACK_stfttp LAPACK_GLOBAL(stfttp,STFTTP) #define LAPACK_ztfttp LAPACK_GLOBAL(ztfttp,ZTFTTP) #define LAPACK_ctfttp LAPACK_GLOBAL(ctfttp,CTFTTP) #define LAPACK_dtfttr LAPACK_GLOBAL(dtfttr,DTFTTR) #define LAPACK_stfttr LAPACK_GLOBAL(stfttr,STFTTR) #define LAPACK_ztfttr LAPACK_GLOBAL(ztfttr,ZTFTTR) #define LAPACK_ctfttr LAPACK_GLOBAL(ctfttr,CTFTTR) #define LAPACK_dtpttf LAPACK_GLOBAL(dtpttf,DTPTTF) #define LAPACK_stpttf LAPACK_GLOBAL(stpttf,STPTTF) #define LAPACK_ztpttf LAPACK_GLOBAL(ztpttf,ZTPTTF) #define LAPACK_ctpttf LAPACK_GLOBAL(ctpttf,CTPTTF) #define LAPACK_dtpttr LAPACK_GLOBAL(dtpttr,DTPTTR) #define LAPACK_stpttr LAPACK_GLOBAL(stpttr,STPTTR) #define LAPACK_ztpttr LAPACK_GLOBAL(ztpttr,ZTPTTR) #define LAPACK_ctpttr LAPACK_GLOBAL(ctpttr,CTPTTR) #define LAPACK_dtrttf LAPACK_GLOBAL(dtrttf,DTRTTF) #define LAPACK_strttf LAPACK_GLOBAL(strttf,STRTTF) #define LAPACK_ztrttf LAPACK_GLOBAL(ztrttf,ZTRTTF) #define LAPACK_ctrttf LAPACK_GLOBAL(ctrttf,CTRTTF) #define LAPACK_dtrttp LAPACK_GLOBAL(dtrttp,DTRTTP) #define LAPACK_strttp LAPACK_GLOBAL(strttp,STRTTP) #define LAPACK_ztrttp LAPACK_GLOBAL(ztrttp,ZTRTTP) #define LAPACK_ctrttp LAPACK_GLOBAL(ctrttp,CTRTTP) #define LAPACK_sgeqrfp LAPACK_GLOBAL(sgeqrfp,SGEQRFP) #define LAPACK_dgeqrfp LAPACK_GLOBAL(dgeqrfp,DGEQRFP) #define LAPACK_cgeqrfp LAPACK_GLOBAL(cgeqrfp,CGEQRFP) #define LAPACK_zgeqrfp LAPACK_GLOBAL(zgeqrfp,ZGEQRFP) #define LAPACK_clacgv LAPACK_GLOBAL(clacgv,CLACGV) #define LAPACK_zlacgv LAPACK_GLOBAL(zlacgv,ZLACGV) #define LAPACK_slarnv LAPACK_GLOBAL(slarnv,SLARNV) #define LAPACK_dlarnv LAPACK_GLOBAL(dlarnv,DLARNV) #define LAPACK_clarnv LAPACK_GLOBAL(clarnv,CLARNV) #define LAPACK_zlarnv LAPACK_GLOBAL(zlarnv,ZLARNV) #define LAPACK_sgeqr2 LAPACK_GLOBAL(sgeqr2,SGEQR2) #define LAPACK_dgeqr2 LAPACK_GLOBAL(dgeqr2,DGEQR2) #define LAPACK_cgeqr2 LAPACK_GLOBAL(cgeqr2,CGEQR2) #define LAPACK_zgeqr2 LAPACK_GLOBAL(zgeqr2,ZGEQR2) #define LAPACK_slacn2 LAPACK_GLOBAL(slacn2,SLACN2) #define LAPACK_dlacn2 LAPACK_GLOBAL(dlacn2,DLACN2) #define LAPACK_clacn2 LAPACK_GLOBAL(clacn2,CLACN2) #define LAPACK_zlacn2 LAPACK_GLOBAL(zlacn2,ZLACN2) #define LAPACK_slacpy LAPACK_GLOBAL(slacpy,SLACPY) #define LAPACK_dlacpy LAPACK_GLOBAL(dlacpy,DLACPY) #define LAPACK_clacpy LAPACK_GLOBAL(clacpy,CLACPY) #define LAPACK_zlacpy LAPACK_GLOBAL(zlacpy,ZLACPY) #define LAPACK_clacp2 LAPACK_GLOBAL(clacp2,CLACP2) #define LAPACK_zlacp2 LAPACK_GLOBAL(zlacp2,ZLACP2) #define LAPACK_sgetf2 LAPACK_GLOBAL(sgetf2,SGETF2) #define LAPACK_dgetf2 LAPACK_GLOBAL(dgetf2,DGETF2) #define LAPACK_cgetf2 LAPACK_GLOBAL(cgetf2,CGETF2) #define LAPACK_zgetf2 LAPACK_GLOBAL(zgetf2,ZGETF2) #define LAPACK_slaswp LAPACK_GLOBAL(slaswp,SLASWP) #define LAPACK_dlaswp LAPACK_GLOBAL(dlaswp,DLASWP) #define LAPACK_claswp LAPACK_GLOBAL(claswp,CLASWP) #define LAPACK_zlaswp LAPACK_GLOBAL(zlaswp,ZLASWP) #define LAPACK_slange LAPACK_GLOBAL(slange,SLANGE) #define LAPACK_dlange LAPACK_GLOBAL(dlange,DLANGE) #define LAPACK_clange LAPACK_GLOBAL(clange,CLANGE) #define LAPACK_zlange LAPACK_GLOBAL(zlange,ZLANGE) #define LAPACK_clanhe LAPACK_GLOBAL(clanhe,CLANHE) #define LAPACK_zlanhe LAPACK_GLOBAL(zlanhe,ZLANHE) #define LAPACK_slansy LAPACK_GLOBAL(slansy,SLANSY) #define LAPACK_dlansy LAPACK_GLOBAL(dlansy,DLANSY) #define LAPACK_clansy LAPACK_GLOBAL(clansy,CLANSY) #define LAPACK_zlansy LAPACK_GLOBAL(zlansy,ZLANSY) #define LAPACK_slantr LAPACK_GLOBAL(slantr,SLANTR) #define LAPACK_dlantr LAPACK_GLOBAL(dlantr,DLANTR) #define LAPACK_clantr LAPACK_GLOBAL(clantr,CLANTR) #define LAPACK_zlantr LAPACK_GLOBAL(zlantr,ZLANTR) #define LAPACK_slamch LAPACK_GLOBAL(slamch,SLAMCH) #define LAPACK_dlamch LAPACK_GLOBAL(dlamch,DLAMCH) #define LAPACK_sgelq2 LAPACK_GLOBAL(sgelq2,SGELQ2) #define LAPACK_dgelq2 LAPACK_GLOBAL(dgelq2,DGELQ2) #define LAPACK_cgelq2 LAPACK_GLOBAL(cgelq2,CGELQ2) #define LAPACK_zgelq2 LAPACK_GLOBAL(zgelq2,ZGELQ2) #define LAPACK_slarfb LAPACK_GLOBAL(slarfb,SLARFB) #define LAPACK_dlarfb LAPACK_GLOBAL(dlarfb,DLARFB) #define LAPACK_clarfb LAPACK_GLOBAL(clarfb,CLARFB) #define LAPACK_zlarfb LAPACK_GLOBAL(zlarfb,ZLARFB) #define LAPACK_slarfg LAPACK_GLOBAL(slarfg,SLARFG) #define LAPACK_dlarfg LAPACK_GLOBAL(dlarfg,DLARFG) #define LAPACK_clarfg LAPACK_GLOBAL(clarfg,CLARFG) #define LAPACK_zlarfg LAPACK_GLOBAL(zlarfg,ZLARFG) #define LAPACK_slarft LAPACK_GLOBAL(slarft,SLARFT) #define LAPACK_dlarft LAPACK_GLOBAL(dlarft,DLARFT) #define LAPACK_clarft LAPACK_GLOBAL(clarft,CLARFT) #define LAPACK_zlarft LAPACK_GLOBAL(zlarft,ZLARFT) #define LAPACK_slarfx LAPACK_GLOBAL(slarfx,SLARFX) #define LAPACK_dlarfx LAPACK_GLOBAL(dlarfx,DLARFX) #define LAPACK_clarfx LAPACK_GLOBAL(clarfx,CLARFX) #define LAPACK_zlarfx LAPACK_GLOBAL(zlarfx,ZLARFX) #define LAPACK_slatms LAPACK_GLOBAL(slatms,SLATMS) #define LAPACK_dlatms LAPACK_GLOBAL(dlatms,DLATMS) #define LAPACK_clatms LAPACK_GLOBAL(clatms,CLATMS) #define LAPACK_zlatms LAPACK_GLOBAL(zlatms,ZLATMS) #define LAPACK_slag2d LAPACK_GLOBAL(slag2d,SLAG2D) #define LAPACK_dlag2s LAPACK_GLOBAL(dlag2s,DLAG2S) #define LAPACK_clag2z LAPACK_GLOBAL(clag2z,CLAG2Z) #define LAPACK_zlag2c LAPACK_GLOBAL(zlag2c,ZLAG2C) #define LAPACK_slauum LAPACK_GLOBAL(slauum,SLAUUM) #define LAPACK_dlauum LAPACK_GLOBAL(dlauum,DLAUUM) #define LAPACK_clauum LAPACK_GLOBAL(clauum,CLAUUM) #define LAPACK_zlauum LAPACK_GLOBAL(zlauum,ZLAUUM) #define LAPACK_slagge LAPACK_GLOBAL(slagge,SLAGGE) #define LAPACK_dlagge LAPACK_GLOBAL(dlagge,DLAGGE) #define LAPACK_clagge LAPACK_GLOBAL(clagge,CLAGGE) #define LAPACK_zlagge LAPACK_GLOBAL(zlagge,ZLAGGE) #define LAPACK_slaset LAPACK_GLOBAL(slaset,SLASET) #define LAPACK_dlaset LAPACK_GLOBAL(dlaset,DLASET) #define LAPACK_claset LAPACK_GLOBAL(claset,CLASET) #define LAPACK_zlaset LAPACK_GLOBAL(zlaset,ZLASET) #define LAPACK_slasrt LAPACK_GLOBAL(slasrt,SLASRT) #define LAPACK_dlasrt LAPACK_GLOBAL(dlasrt,DLASRT) #define LAPACK_slagsy LAPACK_GLOBAL(slagsy,SLAGSY) #define LAPACK_dlagsy LAPACK_GLOBAL(dlagsy,DLAGSY) #define LAPACK_clagsy LAPACK_GLOBAL(clagsy,CLAGSY) #define LAPACK_zlagsy LAPACK_GLOBAL(zlagsy,ZLAGSY) #define LAPACK_claghe LAPACK_GLOBAL(claghe,CLAGHE) #define LAPACK_zlaghe LAPACK_GLOBAL(zlaghe,ZLAGHE) #define LAPACK_slapmr LAPACK_GLOBAL(slapmr,SLAPMR) #define LAPACK_dlapmr LAPACK_GLOBAL(dlapmr,DLAPMR) #define LAPACK_clapmr LAPACK_GLOBAL(clapmr,CLAPMR) #define LAPACK_zlapmr LAPACK_GLOBAL(zlapmr,ZLAPMR) #define LAPACK_slapy2 LAPACK_GLOBAL(slapy2,SLAPY2) #define LAPACK_dlapy2 LAPACK_GLOBAL(dlapy2,DLAPY2) #define LAPACK_slapy3 LAPACK_GLOBAL(slapy3,SLAPY3) #define LAPACK_dlapy3 LAPACK_GLOBAL(dlapy3,DLAPY3) #define LAPACK_slartgp LAPACK_GLOBAL(slartgp,SLARTGP) #define LAPACK_dlartgp LAPACK_GLOBAL(dlartgp,DLARTGP) #define LAPACK_slartgs LAPACK_GLOBAL(slartgs,SLARTGS) #define LAPACK_dlartgs LAPACK_GLOBAL(dlartgs,DLARTGS) // LAPACK 3.3.0 #define LAPACK_cbbcsd LAPACK_GLOBAL(cbbcsd,CBBCSD) #define LAPACK_cheswapr LAPACK_GLOBAL(cheswapr,CHESWAPR) #define LAPACK_chetri2 LAPACK_GLOBAL(chetri2,CHETRI2) #define LAPACK_chetri2x LAPACK_GLOBAL(chetri2x,CHETRI2X) #define LAPACK_chetrs2 LAPACK_GLOBAL(chetrs2,CHETRS2) #define LAPACK_csyconv LAPACK_GLOBAL(csyconv,CSYCONV) #define LAPACK_csyswapr LAPACK_GLOBAL(csyswapr,CSYSWAPR) #define LAPACK_csytri2 LAPACK_GLOBAL(csytri2,CSYTRI2) #define LAPACK_csytri2x LAPACK_GLOBAL(csytri2x,CSYTRI2X) #define LAPACK_csytrs2 LAPACK_GLOBAL(csytrs2,CSYTRS2) #define LAPACK_cunbdb LAPACK_GLOBAL(cunbdb,CUNBDB) #define LAPACK_cuncsd LAPACK_GLOBAL(cuncsd,CUNCSD) #define LAPACK_dbbcsd LAPACK_GLOBAL(dbbcsd,DBBCSD) #define LAPACK_dorbdb LAPACK_GLOBAL(dorbdb,DORBDB) #define LAPACK_dorcsd LAPACK_GLOBAL(dorcsd,DORCSD) #define LAPACK_dsyconv LAPACK_GLOBAL(dsyconv,DSYCONV) #define LAPACK_dsyswapr LAPACK_GLOBAL(dsyswapr,DSYSWAPR) #define LAPACK_dsytri2 LAPACK_GLOBAL(dsytri2,DSYTRI2) #define LAPACK_dsytri2x LAPACK_GLOBAL(dsytri2x,DSYTRI2X) #define LAPACK_dsytrs2 LAPACK_GLOBAL(dsytrs2,DSYTRS2) #define LAPACK_sbbcsd LAPACK_GLOBAL(sbbcsd,SBBCSD) #define LAPACK_sorbdb LAPACK_GLOBAL(sorbdb,SORBDB) #define LAPACK_sorcsd LAPACK_GLOBAL(sorcsd,SORCSD) #define LAPACK_ssyconv LAPACK_GLOBAL(ssyconv,SSYCONV) #define LAPACK_ssyswapr LAPACK_GLOBAL(ssyswapr,SSYSWAPR) #define LAPACK_ssytri2 LAPACK_GLOBAL(ssytri2,SSYTRI2) #define LAPACK_ssytri2x LAPACK_GLOBAL(ssytri2x,SSYTRI2X) #define LAPACK_ssytrs2 LAPACK_GLOBAL(ssytrs2,SSYTRS2) #define LAPACK_zbbcsd LAPACK_GLOBAL(zbbcsd,ZBBCSD) #define LAPACK_zheswapr LAPACK_GLOBAL(zheswapr,ZHESWAPR) #define LAPACK_zhetri2 LAPACK_GLOBAL(zhetri2,ZHETRI2) #define LAPACK_zhetri2x LAPACK_GLOBAL(zhetri2x,ZHETRI2X) #define LAPACK_zhetrs2 LAPACK_GLOBAL(zhetrs2,ZHETRS2) #define LAPACK_zsyconv LAPACK_GLOBAL(zsyconv,ZSYCONV) #define LAPACK_zsyswapr LAPACK_GLOBAL(zsyswapr,ZSYSWAPR) #define LAPACK_zsytri2 LAPACK_GLOBAL(zsytri2,ZSYTRI2) #define LAPACK_zsytri2x LAPACK_GLOBAL(zsytri2x,ZSYTRI2X) #define LAPACK_zsytrs2 LAPACK_GLOBAL(zsytrs2,ZSYTRS2) #define LAPACK_zunbdb LAPACK_GLOBAL(zunbdb,ZUNBDB) #define LAPACK_zuncsd LAPACK_GLOBAL(zuncsd,ZUNCSD) // LAPACK 3.4.0 #define LAPACK_sgemqrt LAPACK_GLOBAL(sgemqrt,SGEMQRT) #define LAPACK_dgemqrt LAPACK_GLOBAL(dgemqrt,DGEMQRT) #define LAPACK_cgemqrt LAPACK_GLOBAL(cgemqrt,CGEMQRT) #define LAPACK_zgemqrt LAPACK_GLOBAL(zgemqrt,ZGEMQRT) #define LAPACK_sgeqrt LAPACK_GLOBAL(sgeqrt,SGEQRT) #define LAPACK_dgeqrt LAPACK_GLOBAL(dgeqrt,DGEQRT) #define LAPACK_cgeqrt LAPACK_GLOBAL(cgeqrt,CGEQRT) #define LAPACK_zgeqrt LAPACK_GLOBAL(zgeqrt,ZGEQRT) #define LAPACK_sgeqrt2 LAPACK_GLOBAL(sgeqrt2,SGEQRT2) #define LAPACK_dgeqrt2 LAPACK_GLOBAL(dgeqrt2,DGEQRT2) #define LAPACK_cgeqrt2 LAPACK_GLOBAL(cgeqrt2,CGEQRT2) #define LAPACK_zgeqrt2 LAPACK_GLOBAL(zgeqrt2,ZGEQRT2) #define LAPACK_sgeqrt3 LAPACK_GLOBAL(sgeqrt3,SGEQRT3) #define LAPACK_dgeqrt3 LAPACK_GLOBAL(dgeqrt3,DGEQRT3) #define LAPACK_cgeqrt3 LAPACK_GLOBAL(cgeqrt3,CGEQRT3) #define LAPACK_zgeqrt3 LAPACK_GLOBAL(zgeqrt3,ZGEQRT3) #define LAPACK_stpmqrt LAPACK_GLOBAL(stpmqrt,STPMQRT) #define LAPACK_dtpmqrt LAPACK_GLOBAL(dtpmqrt,DTPMQRT) #define LAPACK_ctpmqrt LAPACK_GLOBAL(ctpmqrt,CTPMQRT) #define LAPACK_ztpmqrt LAPACK_GLOBAL(ztpmqrt,ZTPMQRT) #define LAPACK_dtpqrt LAPACK_GLOBAL(dtpqrt,DTPQRT) #define LAPACK_ctpqrt LAPACK_GLOBAL(ctpqrt,CTPQRT) #define LAPACK_ztpqrt LAPACK_GLOBAL(ztpqrt,ZTPQRT) #define LAPACK_stpqrt2 LAPACK_GLOBAL(stpqrt2,STPQRT2) #define LAPACK_dtpqrt2 LAPACK_GLOBAL(dtpqrt2,DTPQRT2) #define LAPACK_ctpqrt2 LAPACK_GLOBAL(ctpqrt2,CTPQRT2) #define LAPACK_ztpqrt2 LAPACK_GLOBAL(ztpqrt2,ZTPQRT2) #define LAPACK_stprfb LAPACK_GLOBAL(stprfb,STPRFB) #define LAPACK_dtprfb LAPACK_GLOBAL(dtprfb,DTPRFB) #define LAPACK_ctprfb LAPACK_GLOBAL(ctprfb,CTPRFB) #define LAPACK_ztprfb LAPACK_GLOBAL(ztprfb,ZTPRFB) // LAPACK 3.X.X #define LAPACK_ssysv_rook LAPACK_GLOBAL(ssysv_rook,SSYSV_ROOK) #define LAPACK_dsysv_rook LAPACK_GLOBAL(dsysv_rook,DSYSV_ROOK) #define LAPACK_csysv_rook LAPACK_GLOBAL(csysv_rook,CSYSV_ROOK) #define LAPACK_zsysv_rook LAPACK_GLOBAL(zsysv_rook,ZSYSV_ROOK) #define LAPACK_csyr LAPACK_GLOBAL(csyr,CSYR) #define LAPACK_zsyr LAPACK_GLOBAL(zsyr,ZSYR) #define LAPACK_ilaver LAPACK_GLOBAL(ilaver,ILAVER) void LAPACK_sgetrf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_dgetrf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_cgetrf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_zgetrf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_sgbtrf( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, float* ab, lapack_int* ldab, lapack_int* ipiv, lapack_int *info ); void LAPACK_dgbtrf( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, double* ab, lapack_int* ldab, lapack_int* ipiv, lapack_int *info ); void LAPACK_cgbtrf( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_complex_float* ab, lapack_int* ldab, lapack_int* ipiv, lapack_int *info ); void LAPACK_zgbtrf( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_complex_double* ab, lapack_int* ldab, lapack_int* ipiv, lapack_int *info ); void LAPACK_sgttrf( lapack_int* n, float* dl, float* d, float* du, float* du2, lapack_int* ipiv, lapack_int *info ); void LAPACK_dgttrf( lapack_int* n, double* dl, double* d, double* du, double* du2, lapack_int* ipiv, lapack_int *info ); void LAPACK_cgttrf( lapack_int* n, lapack_complex_float* dl, lapack_complex_float* d, lapack_complex_float* du, lapack_complex_float* du2, lapack_int* ipiv, lapack_int *info ); void LAPACK_zgttrf( lapack_int* n, lapack_complex_double* dl, lapack_complex_double* d, lapack_complex_double* du, lapack_complex_double* du2, lapack_int* ipiv, lapack_int *info ); void LAPACK_spotrf( char* uplo, lapack_int* n, float* a, lapack_int* lda, lapack_int *info ); void LAPACK_dpotrf( char* uplo, lapack_int* n, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_cpotrf( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int *info ); void LAPACK_zpotrf( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_dpstrf( char* uplo, lapack_int* n, double* a, lapack_int* lda, lapack_int* piv, lapack_int* rank, double* tol, double* work, lapack_int *info ); void LAPACK_spstrf( char* uplo, lapack_int* n, float* a, lapack_int* lda, lapack_int* piv, lapack_int* rank, float* tol, float* work, lapack_int *info ); void LAPACK_zpstrf( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* piv, lapack_int* rank, double* tol, double* work, lapack_int *info ); void LAPACK_cpstrf( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* piv, lapack_int* rank, float* tol, float* work, lapack_int *info ); void LAPACK_dpftrf( char* transr, char* uplo, lapack_int* n, double* a, lapack_int *info ); void LAPACK_spftrf( char* transr, char* uplo, lapack_int* n, float* a, lapack_int *info ); void LAPACK_zpftrf( char* transr, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int *info ); void LAPACK_cpftrf( char* transr, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int *info ); void LAPACK_spptrf( char* uplo, lapack_int* n, float* ap, lapack_int *info ); void LAPACK_dpptrf( char* uplo, lapack_int* n, double* ap, lapack_int *info ); void LAPACK_cpptrf( char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_int *info ); void LAPACK_zpptrf( char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_int *info ); void LAPACK_spbtrf( char* uplo, lapack_int* n, lapack_int* kd, float* ab, lapack_int* ldab, lapack_int *info ); void LAPACK_dpbtrf( char* uplo, lapack_int* n, lapack_int* kd, double* ab, lapack_int* ldab, lapack_int *info ); void LAPACK_cpbtrf( char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_float* ab, lapack_int* ldab, lapack_int *info ); void LAPACK_zpbtrf( char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_double* ab, lapack_int* ldab, lapack_int *info ); void LAPACK_spttrf( lapack_int* n, float* d, float* e, lapack_int *info ); void LAPACK_dpttrf( lapack_int* n, double* d, double* e, lapack_int *info ); void LAPACK_cpttrf( lapack_int* n, float* d, lapack_complex_float* e, lapack_int *info ); void LAPACK_zpttrf( lapack_int* n, double* d, lapack_complex_double* e, lapack_int *info ); void LAPACK_ssytrf( char* uplo, lapack_int* n, float* a, lapack_int* lda, lapack_int* ipiv, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dsytrf( char* uplo, lapack_int* n, double* a, lapack_int* lda, lapack_int* ipiv, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_csytrf( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zsytrf( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_chetrf( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zhetrf( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ssptrf( char* uplo, lapack_int* n, float* ap, lapack_int* ipiv, lapack_int *info ); void LAPACK_dsptrf( char* uplo, lapack_int* n, double* ap, lapack_int* ipiv, lapack_int *info ); void LAPACK_csptrf( char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_int* ipiv, lapack_int *info ); void LAPACK_zsptrf( char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_int* ipiv, lapack_int *info ); void LAPACK_chptrf( char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_int* ipiv, lapack_int *info ); void LAPACK_zhptrf( char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_int* ipiv, lapack_int *info ); void LAPACK_sgetrs( char* trans, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dgetrs( char* trans, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cgetrs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zgetrs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sgbtrs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const float* ab, lapack_int* ldab, const lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dgbtrs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const double* ab, lapack_int* ldab, const lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cgbtrs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zgbtrs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sgttrs( char* trans, lapack_int* n, lapack_int* nrhs, const float* dl, const float* d, const float* du, const float* du2, const lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dgttrs( char* trans, lapack_int* n, lapack_int* nrhs, const double* dl, const double* d, const double* du, const double* du2, const lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cgttrs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* du2, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zgttrs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* du2, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_spotrs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dpotrs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cpotrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zpotrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dpftrs( char* transr, char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_spftrs( char* transr, char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zpftrs( char* transr, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cpftrs( char* transr, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_spptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* ap, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dpptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* ap, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cpptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zpptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_spbtrs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const float* ab, lapack_int* ldab, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dpbtrs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const double* ab, lapack_int* ldab, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cpbtrs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zpbtrs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_spttrs( lapack_int* n, lapack_int* nrhs, const float* d, const float* e, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dpttrs( lapack_int* n, lapack_int* nrhs, const double* d, const double* e, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cpttrs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* d, const lapack_complex_float* e, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zpttrs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* d, const lapack_complex_double* e, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ssytrs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dsytrs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_csytrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zsytrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_chetrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zhetrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ssptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* ap, const lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dsptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* ap, const lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_csptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zsptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_chptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zhptrs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_strtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dtrtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ctrtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ztrtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_stptrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const float* ap, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dtptrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const double* ap, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ctptrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ztptrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_stbtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const float* ab, lapack_int* ldab, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dtbtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const double* ab, lapack_int* ldab, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ctbtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_ztbtrs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sgecon( char* norm, lapack_int* n, const float* a, lapack_int* lda, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgecon( char* norm, lapack_int* n, const double* a, lapack_int* lda, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgecon( char* norm, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* anorm, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgecon( char* norm, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* anorm, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sgbcon( char* norm, lapack_int* n, lapack_int* kl, lapack_int* ku, const float* ab, lapack_int* ldab, const lapack_int* ipiv, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgbcon( char* norm, lapack_int* n, lapack_int* kl, lapack_int* ku, const double* ab, lapack_int* ldab, const lapack_int* ipiv, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgbcon( char* norm, lapack_int* n, lapack_int* kl, lapack_int* ku, const lapack_complex_float* ab, lapack_int* ldab, const lapack_int* ipiv, float* anorm, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgbcon( char* norm, lapack_int* n, lapack_int* kl, lapack_int* ku, const lapack_complex_double* ab, lapack_int* ldab, const lapack_int* ipiv, double* anorm, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sgtcon( char* norm, lapack_int* n, const float* dl, const float* d, const float* du, const float* du2, const lapack_int* ipiv, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgtcon( char* norm, lapack_int* n, const double* dl, const double* d, const double* du, const double* du2, const lapack_int* ipiv, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgtcon( char* norm, lapack_int* n, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* du2, const lapack_int* ipiv, float* anorm, float* rcond, lapack_complex_float* work, lapack_int *info ); void LAPACK_zgtcon( char* norm, lapack_int* n, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* du2, const lapack_int* ipiv, double* anorm, double* rcond, lapack_complex_double* work, lapack_int *info ); void LAPACK_spocon( char* uplo, lapack_int* n, const float* a, lapack_int* lda, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dpocon( char* uplo, lapack_int* n, const double* a, lapack_int* lda, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cpocon( char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* anorm, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zpocon( char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* anorm, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sppcon( char* uplo, lapack_int* n, const float* ap, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dppcon( char* uplo, lapack_int* n, const double* ap, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cppcon( char* uplo, lapack_int* n, const lapack_complex_float* ap, float* anorm, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zppcon( char* uplo, lapack_int* n, const lapack_complex_double* ap, double* anorm, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_spbcon( char* uplo, lapack_int* n, lapack_int* kd, const float* ab, lapack_int* ldab, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dpbcon( char* uplo, lapack_int* n, lapack_int* kd, const double* ab, lapack_int* ldab, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cpbcon( char* uplo, lapack_int* n, lapack_int* kd, const lapack_complex_float* ab, lapack_int* ldab, float* anorm, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zpbcon( char* uplo, lapack_int* n, lapack_int* kd, const lapack_complex_double* ab, lapack_int* ldab, double* anorm, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sptcon( lapack_int* n, const float* d, const float* e, float* anorm, float* rcond, float* work, lapack_int *info ); void LAPACK_dptcon( lapack_int* n, const double* d, const double* e, double* anorm, double* rcond, double* work, lapack_int *info ); void LAPACK_cptcon( lapack_int* n, const float* d, const lapack_complex_float* e, float* anorm, float* rcond, float* work, lapack_int *info ); void LAPACK_zptcon( lapack_int* n, const double* d, const lapack_complex_double* e, double* anorm, double* rcond, double* work, lapack_int *info ); void LAPACK_ssycon( char* uplo, lapack_int* n, const float* a, lapack_int* lda, const lapack_int* ipiv, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dsycon( char* uplo, lapack_int* n, const double* a, lapack_int* lda, const lapack_int* ipiv, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_csycon( char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, float* anorm, float* rcond, lapack_complex_float* work, lapack_int *info ); void LAPACK_zsycon( char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, double* anorm, double* rcond, lapack_complex_double* work, lapack_int *info ); void LAPACK_checon( char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, float* anorm, float* rcond, lapack_complex_float* work, lapack_int *info ); void LAPACK_zhecon( char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, double* anorm, double* rcond, lapack_complex_double* work, lapack_int *info ); void LAPACK_sspcon( char* uplo, lapack_int* n, const float* ap, const lapack_int* ipiv, float* anorm, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dspcon( char* uplo, lapack_int* n, const double* ap, const lapack_int* ipiv, double* anorm, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cspcon( char* uplo, lapack_int* n, const lapack_complex_float* ap, const lapack_int* ipiv, float* anorm, float* rcond, lapack_complex_float* work, lapack_int *info ); void LAPACK_zspcon( char* uplo, lapack_int* n, const lapack_complex_double* ap, const lapack_int* ipiv, double* anorm, double* rcond, lapack_complex_double* work, lapack_int *info ); void LAPACK_chpcon( char* uplo, lapack_int* n, const lapack_complex_float* ap, const lapack_int* ipiv, float* anorm, float* rcond, lapack_complex_float* work, lapack_int *info ); void LAPACK_zhpcon( char* uplo, lapack_int* n, const lapack_complex_double* ap, const lapack_int* ipiv, double* anorm, double* rcond, lapack_complex_double* work, lapack_int *info ); void LAPACK_strcon( char* norm, char* uplo, char* diag, lapack_int* n, const float* a, lapack_int* lda, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dtrcon( char* norm, char* uplo, char* diag, lapack_int* n, const double* a, lapack_int* lda, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ctrcon( char* norm, char* uplo, char* diag, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztrcon( char* norm, char* uplo, char* diag, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_stpcon( char* norm, char* uplo, char* diag, lapack_int* n, const float* ap, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dtpcon( char* norm, char* uplo, char* diag, lapack_int* n, const double* ap, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ctpcon( char* norm, char* uplo, char* diag, lapack_int* n, const lapack_complex_float* ap, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztpcon( char* norm, char* uplo, char* diag, lapack_int* n, const lapack_complex_double* ap, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_stbcon( char* norm, char* uplo, char* diag, lapack_int* n, lapack_int* kd, const float* ab, lapack_int* ldab, float* rcond, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dtbcon( char* norm, char* uplo, char* diag, lapack_int* n, lapack_int* kd, const double* ab, lapack_int* ldab, double* rcond, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ctbcon( char* norm, char* uplo, char* diag, lapack_int* n, lapack_int* kd, const lapack_complex_float* ab, lapack_int* ldab, float* rcond, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztbcon( char* norm, char* uplo, char* diag, lapack_int* n, lapack_int* kd, const lapack_complex_double* ab, lapack_int* ldab, double* rcond, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sgerfs( char* trans, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgerfs( char* trans, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgerfs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgerfs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dgerfsx( char* trans, char* equed, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* r, const double* c, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sgerfsx( char* trans, char* equed, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* r, const float* c, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zgerfsx( char* trans, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* r, const double* c, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cgerfsx( char* trans, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* r, const float* c, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_sgbrfs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const float* ab, lapack_int* ldab, const float* afb, lapack_int* ldafb, const lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgbrfs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const double* ab, lapack_int* ldab, const double* afb, lapack_int* ldafb, const lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgbrfs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, const lapack_complex_float* afb, lapack_int* ldafb, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgbrfs( char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, const lapack_complex_double* afb, lapack_int* ldafb, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dgbrfsx( char* trans, char* equed, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const double* ab, lapack_int* ldab, const double* afb, lapack_int* ldafb, const lapack_int* ipiv, const double* r, const double* c, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sgbrfsx( char* trans, char* equed, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const float* ab, lapack_int* ldab, const float* afb, lapack_int* ldafb, const lapack_int* ipiv, const float* r, const float* c, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zgbrfsx( char* trans, char* equed, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, const lapack_complex_double* afb, lapack_int* ldafb, const lapack_int* ipiv, const double* r, const double* c, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cgbrfsx( char* trans, char* equed, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, const lapack_complex_float* afb, lapack_int* ldafb, const lapack_int* ipiv, const float* r, const float* c, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_sgtrfs( char* trans, lapack_int* n, lapack_int* nrhs, const float* dl, const float* d, const float* du, const float* dlf, const float* df, const float* duf, const float* du2, const lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgtrfs( char* trans, lapack_int* n, lapack_int* nrhs, const double* dl, const double* d, const double* du, const double* dlf, const double* df, const double* duf, const double* du2, const lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgtrfs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, const lapack_complex_float* dlf, const lapack_complex_float* df, const lapack_complex_float* duf, const lapack_complex_float* du2, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgtrfs( char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, const lapack_complex_double* dlf, const lapack_complex_double* df, const lapack_complex_double* duf, const lapack_complex_double* du2, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sporfs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* af, lapack_int* ldaf, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dporfs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* af, lapack_int* ldaf, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cporfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zporfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dporfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* af, lapack_int* ldaf, const double* s, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sporfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* af, lapack_int* ldaf, const float* s, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zporfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const double* s, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cporfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const float* s, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_spprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* ap, const float* afp, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dpprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* ap, const double* afp, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cpprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zpprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_spbrfs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const float* ab, lapack_int* ldab, const float* afb, lapack_int* ldafb, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dpbrfs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const double* ab, lapack_int* ldab, const double* afb, lapack_int* ldafb, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cpbrfs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, const lapack_complex_float* afb, lapack_int* ldafb, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zpbrfs( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, const lapack_complex_double* afb, lapack_int* ldafb, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sptrfs( lapack_int* n, lapack_int* nrhs, const float* d, const float* e, const float* df, const float* ef, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int *info ); void LAPACK_dptrfs( lapack_int* n, lapack_int* nrhs, const double* d, const double* e, const double* df, const double* ef, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int *info ); void LAPACK_cptrfs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* d, const lapack_complex_float* e, const float* df, const lapack_complex_float* ef, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zptrfs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* d, const lapack_complex_double* e, const double* df, const lapack_complex_double* ef, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_ssyrfs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dsyrfs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_csyrfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zsyrfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dsyrfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* s, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ssyrfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* s, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zsyrfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* s, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_csyrfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* s, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_cherfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zherfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_zherfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* af, lapack_int* ldaf, const lapack_int* ipiv, const double* s, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cherfsx( char* uplo, char* equed, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* af, lapack_int* ldaf, const lapack_int* ipiv, const float* s, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ssprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const float* ap, const float* afp, const lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dsprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const double* ap, const double* afp, const lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_csprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zsprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_chprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, const lapack_complex_float* afp, const lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhprfs( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, const lapack_complex_double* afp, const lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_strrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const float* b, lapack_int* ldb, const float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dtrrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const double* b, lapack_int* ldb, const double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ctrrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* b, lapack_int* ldb, const lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztrrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* b, lapack_int* ldb, const lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_stprfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const float* ap, const float* b, lapack_int* ldb, const float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dtprfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const double* ap, const double* b, lapack_int* ldb, const double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ctprfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, const lapack_complex_float* b, lapack_int* ldb, const lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztprfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, const lapack_complex_double* b, lapack_int* ldb, const lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_stbrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const float* ab, lapack_int* ldab, const float* b, lapack_int* ldb, const float* x, lapack_int* ldx, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dtbrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const double* ab, lapack_int* ldab, const double* b, lapack_int* ldb, const double* x, lapack_int* ldx, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ctbrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_float* ab, lapack_int* ldab, const lapack_complex_float* b, lapack_int* ldb, const lapack_complex_float* x, lapack_int* ldx, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztbrfs( char* uplo, char* trans, char* diag, lapack_int* n, lapack_int* kd, lapack_int* nrhs, const lapack_complex_double* ab, lapack_int* ldab, const lapack_complex_double* b, lapack_int* ldb, const lapack_complex_double* x, lapack_int* ldx, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sgetri( lapack_int* n, float* a, lapack_int* lda, const lapack_int* ipiv, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgetri( lapack_int* n, double* a, lapack_int* lda, const lapack_int* ipiv, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgetri( lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgetri( lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_spotri( char* uplo, lapack_int* n, float* a, lapack_int* lda, lapack_int *info ); void LAPACK_dpotri( char* uplo, lapack_int* n, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_cpotri( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int *info ); void LAPACK_zpotri( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_dpftri( char* transr, char* uplo, lapack_int* n, double* a, lapack_int *info ); void LAPACK_spftri( char* transr, char* uplo, lapack_int* n, float* a, lapack_int *info ); void LAPACK_zpftri( char* transr, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int *info ); void LAPACK_cpftri( char* transr, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int *info ); void LAPACK_spptri( char* uplo, lapack_int* n, float* ap, lapack_int *info ); void LAPACK_dpptri( char* uplo, lapack_int* n, double* ap, lapack_int *info ); void LAPACK_cpptri( char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_int *info ); void LAPACK_zpptri( char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_int *info ); void LAPACK_ssytri( char* uplo, lapack_int* n, float* a, lapack_int* lda, const lapack_int* ipiv, float* work, lapack_int *info ); void LAPACK_dsytri( char* uplo, lapack_int* n, double* a, lapack_int* lda, const lapack_int* ipiv, double* work, lapack_int *info ); void LAPACK_csytri( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int *info ); void LAPACK_zsytri( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int *info ); void LAPACK_chetri( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int *info ); void LAPACK_zhetri( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int *info ); void LAPACK_ssptri( char* uplo, lapack_int* n, float* ap, const lapack_int* ipiv, float* work, lapack_int *info ); void LAPACK_dsptri( char* uplo, lapack_int* n, double* ap, const lapack_int* ipiv, double* work, lapack_int *info ); void LAPACK_csptri( char* uplo, lapack_int* n, lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* work, lapack_int *info ); void LAPACK_zsptri( char* uplo, lapack_int* n, lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* work, lapack_int *info ); void LAPACK_chptri( char* uplo, lapack_int* n, lapack_complex_float* ap, const lapack_int* ipiv, lapack_complex_float* work, lapack_int *info ); void LAPACK_zhptri( char* uplo, lapack_int* n, lapack_complex_double* ap, const lapack_int* ipiv, lapack_complex_double* work, lapack_int *info ); void LAPACK_strtri( char* uplo, char* diag, lapack_int* n, float* a, lapack_int* lda, lapack_int *info ); void LAPACK_dtrtri( char* uplo, char* diag, lapack_int* n, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_ctrtri( char* uplo, char* diag, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int *info ); void LAPACK_ztrtri( char* uplo, char* diag, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_dtftri( char* transr, char* uplo, char* diag, lapack_int* n, double* a, lapack_int *info ); void LAPACK_stftri( char* transr, char* uplo, char* diag, lapack_int* n, float* a, lapack_int *info ); void LAPACK_ztftri( char* transr, char* uplo, char* diag, lapack_int* n, lapack_complex_double* a, lapack_int *info ); void LAPACK_ctftri( char* transr, char* uplo, char* diag, lapack_int* n, lapack_complex_float* a, lapack_int *info ); void LAPACK_stptri( char* uplo, char* diag, lapack_int* n, float* ap, lapack_int *info ); void LAPACK_dtptri( char* uplo, char* diag, lapack_int* n, double* ap, lapack_int *info ); void LAPACK_ctptri( char* uplo, char* diag, lapack_int* n, lapack_complex_float* ap, lapack_int *info ); void LAPACK_ztptri( char* uplo, char* diag, lapack_int* n, lapack_complex_double* ap, lapack_int *info ); void LAPACK_sgeequ( lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_dgeequ( lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_cgeequ( lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_zgeequ( lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_dgeequb( lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_sgeequb( lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_zgeequb( lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_cgeequb( lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_sgbequ( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const float* ab, lapack_int* ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_dgbequ( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const double* ab, lapack_int* ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_cgbequ( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const lapack_complex_float* ab, lapack_int* ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_zgbequ( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const lapack_complex_double* ab, lapack_int* ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_dgbequb( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const double* ab, lapack_int* ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_sgbequb( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const float* ab, lapack_int* ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_zgbequb( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const lapack_complex_double* ab, lapack_int* ldab, double* r, double* c, double* rowcnd, double* colcnd, double* amax, lapack_int *info ); void LAPACK_cgbequb( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const lapack_complex_float* ab, lapack_int* ldab, float* r, float* c, float* rowcnd, float* colcnd, float* amax, lapack_int *info ); void LAPACK_spoequ( lapack_int* n, const float* a, lapack_int* lda, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_dpoequ( lapack_int* n, const double* a, lapack_int* lda, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_cpoequ( lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_zpoequ( lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_dpoequb( lapack_int* n, const double* a, lapack_int* lda, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_spoequb( lapack_int* n, const float* a, lapack_int* lda, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_zpoequb( lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_cpoequb( lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_sppequ( char* uplo, lapack_int* n, const float* ap, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_dppequ( char* uplo, lapack_int* n, const double* ap, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_cppequ( char* uplo, lapack_int* n, const lapack_complex_float* ap, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_zppequ( char* uplo, lapack_int* n, const lapack_complex_double* ap, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_spbequ( char* uplo, lapack_int* n, lapack_int* kd, const float* ab, lapack_int* ldab, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_dpbequ( char* uplo, lapack_int* n, lapack_int* kd, const double* ab, lapack_int* ldab, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_cpbequ( char* uplo, lapack_int* n, lapack_int* kd, const lapack_complex_float* ab, lapack_int* ldab, float* s, float* scond, float* amax, lapack_int *info ); void LAPACK_zpbequ( char* uplo, lapack_int* n, lapack_int* kd, const lapack_complex_double* ab, lapack_int* ldab, double* s, double* scond, double* amax, lapack_int *info ); void LAPACK_dsyequb( char* uplo, lapack_int* n, const double* a, lapack_int* lda, double* s, double* scond, double* amax, double* work, lapack_int *info ); void LAPACK_ssyequb( char* uplo, lapack_int* n, const float* a, lapack_int* lda, float* s, float* scond, float* amax, float* work, lapack_int *info ); void LAPACK_zsyequb( char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* s, double* scond, double* amax, lapack_complex_double* work, lapack_int *info ); void LAPACK_csyequb( char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* s, float* scond, float* amax, lapack_complex_float* work, lapack_int *info ); void LAPACK_zheequb( char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* s, double* scond, double* amax, lapack_complex_double* work, lapack_int *info ); void LAPACK_cheequb( char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* s, float* scond, float* amax, lapack_complex_float* work, lapack_int *info ); void LAPACK_sgesv( lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dgesv( lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cgesv( lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zgesv( lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dsgesv( lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, lapack_int* ipiv, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* work, float* swork, lapack_int* iter, lapack_int *info ); void LAPACK_zcgesv( lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, lapack_complex_double* work, lapack_complex_float* swork, double* rwork, lapack_int* iter, lapack_int *info ); void LAPACK_sgesvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgesvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgesvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgesvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dgesvxx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sgesvxx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zgesvxx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cgesvxx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_sgbsv( lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, float* ab, lapack_int* ldab, lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dgbsv( lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, double* ab, lapack_int* ldab, lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cgbsv( lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, lapack_complex_float* ab, lapack_int* ldab, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zgbsv( lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, lapack_complex_double* ab, lapack_int* ldab, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sgbsvx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, float* ab, lapack_int* ldab, float* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgbsvx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, double* ab, lapack_int* ldab, double* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgbsvx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgbsvx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dgbsvxx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, double* ab, lapack_int* ldab, double* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, double* r, double* c, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sgbsvxx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, float* ab, lapack_int* ldab, float* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, float* r, float* c, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zgbsvxx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, double* r, double* c, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cgbsvxx( char* fact, char* trans, lapack_int* n, lapack_int* kl, lapack_int* ku, lapack_int* nrhs, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* afb, lapack_int* ldafb, lapack_int* ipiv, char* equed, float* r, float* c, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_sgtsv( lapack_int* n, lapack_int* nrhs, float* dl, float* d, float* du, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dgtsv( lapack_int* n, lapack_int* nrhs, double* dl, double* d, double* du, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cgtsv( lapack_int* n, lapack_int* nrhs, lapack_complex_float* dl, lapack_complex_float* d, lapack_complex_float* du, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zgtsv( lapack_int* n, lapack_int* nrhs, lapack_complex_double* dl, lapack_complex_double* d, lapack_complex_double* du, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sgtsvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, const float* dl, const float* d, const float* du, float* dlf, float* df, float* duf, float* du2, lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dgtsvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, const double* dl, const double* d, const double* du, double* dlf, double* df, double* duf, double* du2, lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cgtsvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* dl, const lapack_complex_float* d, const lapack_complex_float* du, lapack_complex_float* dlf, lapack_complex_float* df, lapack_complex_float* duf, lapack_complex_float* du2, lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgtsvx( char* fact, char* trans, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* dl, const lapack_complex_double* d, const lapack_complex_double* du, lapack_complex_double* dlf, lapack_complex_double* df, lapack_complex_double* duf, lapack_complex_double* du2, lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sposv( char* uplo, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dposv( char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cposv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zposv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dsposv( char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* work, float* swork, lapack_int* iter, lapack_int *info ); void LAPACK_zcposv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, lapack_complex_double* work, lapack_complex_float* swork, double* rwork, lapack_int* iter, lapack_int *info ); void LAPACK_sposvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* af, lapack_int* ldaf, char* equed, float* s, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dposvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* af, lapack_int* ldaf, char* equed, double* s, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cposvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, char* equed, float* s, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zposvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, char* equed, double* s, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_dposvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* af, lapack_int* ldaf, char* equed, double* s, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sposvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* af, lapack_int* ldaf, char* equed, float* s, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zposvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, char* equed, double* s, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_cposvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, char* equed, float* s, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_sppsv( char* uplo, lapack_int* n, lapack_int* nrhs, float* ap, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dppsv( char* uplo, lapack_int* n, lapack_int* nrhs, double* ap, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cppsv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* ap, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zppsv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* ap, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sppsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, float* ap, float* afp, char* equed, float* s, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dppsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, double* ap, double* afp, char* equed, double* s, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cppsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* ap, lapack_complex_float* afp, char* equed, float* s, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zppsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* ap, lapack_complex_double* afp, char* equed, double* s, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_spbsv( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, float* ab, lapack_int* ldab, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dpbsv( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, double* ab, lapack_int* ldab, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cpbsv( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zpbsv( char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_spbsvx( char* fact, char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, float* ab, lapack_int* ldab, float* afb, lapack_int* ldafb, char* equed, float* s, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dpbsvx( char* fact, char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, double* ab, lapack_int* ldab, double* afb, lapack_int* ldafb, char* equed, double* s, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cpbsvx( char* fact, char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* afb, lapack_int* ldafb, char* equed, float* s, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zpbsvx( char* fact, char* uplo, lapack_int* n, lapack_int* kd, lapack_int* nrhs, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* afb, lapack_int* ldafb, char* equed, double* s, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sptsv( lapack_int* n, lapack_int* nrhs, float* d, float* e, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dptsv( lapack_int* n, lapack_int* nrhs, double* d, double* e, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cptsv( lapack_int* n, lapack_int* nrhs, float* d, lapack_complex_float* e, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zptsv( lapack_int* n, lapack_int* nrhs, double* d, lapack_complex_double* e, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sptsvx( char* fact, lapack_int* n, lapack_int* nrhs, const float* d, const float* e, float* df, float* ef, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int *info ); void LAPACK_dptsvx( char* fact, lapack_int* n, lapack_int* nrhs, const double* d, const double* e, double* df, double* ef, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int *info ); void LAPACK_cptsvx( char* fact, lapack_int* n, lapack_int* nrhs, const float* d, const lapack_complex_float* e, float* df, lapack_complex_float* ef, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zptsvx( char* fact, lapack_int* n, lapack_int* nrhs, const double* d, const lapack_complex_double* e, double* df, lapack_complex_double* ef, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_ssysv( char* uplo, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, lapack_int* ipiv, float* b, lapack_int* ldb, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dsysv( char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, lapack_int* ipiv, double* b, lapack_int* ldb, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_csysv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zsysv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ssysvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, float* af, lapack_int* ldaf, lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dsysvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, double* af, lapack_int* ldaf, lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_csysvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zsysvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_dsysvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* s, double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ssysvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* s, float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_zsysvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* s, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_csysvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* s, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_chesv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zhesv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_chesvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zhesvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_zhesvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, double* s, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* rpvgrw, double* berr, lapack_int* n_err_bnds, double* err_bnds_norm, double* err_bnds_comp, lapack_int* nparams, double* params, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_chesvxx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* af, lapack_int* ldaf, lapack_int* ipiv, char* equed, float* s, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* rpvgrw, float* berr, lapack_int* n_err_bnds, float* err_bnds_norm, float* err_bnds_comp, lapack_int* nparams, float* params, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_sspsv( char* uplo, lapack_int* n, lapack_int* nrhs, float* ap, lapack_int* ipiv, float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dspsv( char* uplo, lapack_int* n, lapack_int* nrhs, double* ap, lapack_int* ipiv, double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_cspsv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* ap, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zspsv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* ap, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sspsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const float* ap, float* afp, lapack_int* ipiv, const float* b, lapack_int* ldb, float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dspsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const double* ap, double* afp, lapack_int* ipiv, const double* b, lapack_int* ldb, double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cspsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, lapack_complex_float* afp, lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zspsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, lapack_complex_double* afp, lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_chpsv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* ap, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zhpsv( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* ap, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_chpsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* ap, lapack_complex_float* afp, lapack_int* ipiv, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* x, lapack_int* ldx, float* rcond, float* ferr, float* berr, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhpsvx( char* fact, char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* ap, lapack_complex_double* afp, lapack_int* ipiv, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* x, lapack_int* ldx, double* rcond, double* ferr, double* berr, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sgeqrf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgeqrf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgeqrf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgeqrf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgeqpf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, lapack_int* jpvt, float* tau, float* work, lapack_int *info ); void LAPACK_dgeqpf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, lapack_int* jpvt, double* tau, double* work, lapack_int *info ); void LAPACK_cgeqpf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* jpvt, lapack_complex_float* tau, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgeqpf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* jpvt, lapack_complex_double* tau, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sgeqp3( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, lapack_int* jpvt, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgeqp3( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, lapack_int* jpvt, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgeqp3( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* jpvt, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zgeqp3( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* jpvt, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sorgqr( lapack_int* m, lapack_int* n, lapack_int* k, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorgqr( lapack_int* m, lapack_int* n, lapack_int* k, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormqr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormqr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cungqr( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zungqr( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmqr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmqr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgelqf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgelqf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgelqf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgelqf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sorglq( lapack_int* m, lapack_int* n, lapack_int* k, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorglq( lapack_int* m, lapack_int* n, lapack_int* k, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormlq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormlq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunglq( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunglq( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmlq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmlq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgeqlf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgeqlf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgeqlf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgeqlf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sorgql( lapack_int* m, lapack_int* n, lapack_int* k, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorgql( lapack_int* m, lapack_int* n, lapack_int* k, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cungql( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zungql( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormql( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormql( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmql( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmql( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgerqf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgerqf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgerqf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgerqf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sorgrq( lapack_int* m, lapack_int* n, lapack_int* k, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorgrq( lapack_int* m, lapack_int* n, lapack_int* k, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cungrq( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zungrq( lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormrq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormrq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmrq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmrq( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_stzrzf( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dtzrzf( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ctzrzf( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ztzrzf( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormrz( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormrz( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmrz( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmrz( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sggqrf( lapack_int* n, lapack_int* m, lapack_int* p, float* a, lapack_int* lda, float* taua, float* b, lapack_int* ldb, float* taub, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dggqrf( lapack_int* n, lapack_int* m, lapack_int* p, double* a, lapack_int* lda, double* taua, double* b, lapack_int* ldb, double* taub, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cggqrf( lapack_int* n, lapack_int* m, lapack_int* p, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* taua, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* taub, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zggqrf( lapack_int* n, lapack_int* m, lapack_int* p, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* taua, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* taub, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sggrqf( lapack_int* m, lapack_int* p, lapack_int* n, float* a, lapack_int* lda, float* taua, float* b, lapack_int* ldb, float* taub, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dggrqf( lapack_int* m, lapack_int* p, lapack_int* n, double* a, lapack_int* lda, double* taua, double* b, lapack_int* ldb, double* taub, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cggrqf( lapack_int* m, lapack_int* p, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* taua, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* taub, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zggrqf( lapack_int* m, lapack_int* p, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* taua, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* taub, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgebrd( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* d, float* e, float* tauq, float* taup, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgebrd( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* d, double* e, double* tauq, double* taup, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgebrd( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* d, float* e, lapack_complex_float* tauq, lapack_complex_float* taup, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgebrd( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* d, double* e, lapack_complex_double* tauq, lapack_complex_double* taup, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgbbrd( char* vect, lapack_int* m, lapack_int* n, lapack_int* ncc, lapack_int* kl, lapack_int* ku, float* ab, lapack_int* ldab, float* d, float* e, float* q, lapack_int* ldq, float* pt, lapack_int* ldpt, float* c, lapack_int* ldc, float* work, lapack_int *info ); void LAPACK_dgbbrd( char* vect, lapack_int* m, lapack_int* n, lapack_int* ncc, lapack_int* kl, lapack_int* ku, double* ab, lapack_int* ldab, double* d, double* e, double* q, lapack_int* ldq, double* pt, lapack_int* ldpt, double* c, lapack_int* ldc, double* work, lapack_int *info ); void LAPACK_cgbbrd( char* vect, lapack_int* m, lapack_int* n, lapack_int* ncc, lapack_int* kl, lapack_int* ku, lapack_complex_float* ab, lapack_int* ldab, float* d, float* e, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* pt, lapack_int* ldpt, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zgbbrd( char* vect, lapack_int* m, lapack_int* n, lapack_int* ncc, lapack_int* kl, lapack_int* ku, lapack_complex_double* ab, lapack_int* ldab, double* d, double* e, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* pt, lapack_int* ldpt, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sorgbr( char* vect, lapack_int* m, lapack_int* n, lapack_int* k, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorgbr( char* vect, lapack_int* m, lapack_int* n, lapack_int* k, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormbr( char* vect, char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormbr( char* vect, char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cungbr( char* vect, lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zungbr( char* vect, lapack_int* m, lapack_int* n, lapack_int* k, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmbr( char* vect, char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmbr( char* vect, char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sbdsqr( char* uplo, lapack_int* n, lapack_int* ncvt, lapack_int* nru, lapack_int* ncc, float* d, float* e, float* vt, lapack_int* ldvt, float* u, lapack_int* ldu, float* c, lapack_int* ldc, float* work, lapack_int *info ); void LAPACK_dbdsqr( char* uplo, lapack_int* n, lapack_int* ncvt, lapack_int* nru, lapack_int* ncc, double* d, double* e, double* vt, lapack_int* ldvt, double* u, lapack_int* ldu, double* c, lapack_int* ldc, double* work, lapack_int *info ); void LAPACK_cbdsqr( char* uplo, lapack_int* n, lapack_int* ncvt, lapack_int* nru, lapack_int* ncc, float* d, float* e, lapack_complex_float* vt, lapack_int* ldvt, lapack_complex_float* u, lapack_int* ldu, lapack_complex_float* c, lapack_int* ldc, float* work, lapack_int *info ); void LAPACK_zbdsqr( char* uplo, lapack_int* n, lapack_int* ncvt, lapack_int* nru, lapack_int* ncc, double* d, double* e, lapack_complex_double* vt, lapack_int* ldvt, lapack_complex_double* u, lapack_int* ldu, lapack_complex_double* c, lapack_int* ldc, double* work, lapack_int *info ); void LAPACK_sbdsdc( char* uplo, char* compq, lapack_int* n, float* d, float* e, float* u, lapack_int* ldu, float* vt, lapack_int* ldvt, float* q, lapack_int* iq, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dbdsdc( char* uplo, char* compq, lapack_int* n, double* d, double* e, double* u, lapack_int* ldu, double* vt, lapack_int* ldvt, double* q, lapack_int* iq, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_ssytrd( char* uplo, lapack_int* n, float* a, lapack_int* lda, float* d, float* e, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dsytrd( char* uplo, lapack_int* n, double* a, lapack_int* lda, double* d, double* e, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sorgtr( char* uplo, lapack_int* n, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorgtr( char* uplo, lapack_int* n, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_chetrd( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* d, float* e, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zhetrd( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* d, double* e, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cungtr( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zungtr( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ssptrd( char* uplo, lapack_int* n, float* ap, float* d, float* e, float* tau, lapack_int *info ); void LAPACK_dsptrd( char* uplo, lapack_int* n, double* ap, double* d, double* e, double* tau, lapack_int *info ); void LAPACK_sopgtr( char* uplo, lapack_int* n, const float* ap, const float* tau, float* q, lapack_int* ldq, float* work, lapack_int *info ); void LAPACK_dopgtr( char* uplo, lapack_int* n, const double* ap, const double* tau, double* q, lapack_int* ldq, double* work, lapack_int *info ); void LAPACK_sopmtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const float* ap, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int *info ); void LAPACK_dopmtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const double* ap, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int *info ); void LAPACK_chptrd( char* uplo, lapack_int* n, lapack_complex_float* ap, float* d, float* e, lapack_complex_float* tau, lapack_int *info ); void LAPACK_zhptrd( char* uplo, lapack_int* n, lapack_complex_double* ap, double* d, double* e, lapack_complex_double* tau, lapack_int *info ); void LAPACK_cupgtr( char* uplo, lapack_int* n, const lapack_complex_float* ap, const lapack_complex_float* tau, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* work, lapack_int *info ); void LAPACK_zupgtr( char* uplo, lapack_int* n, const lapack_complex_double* ap, const lapack_complex_double* tau, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* work, lapack_int *info ); void LAPACK_cupmtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const lapack_complex_float* ap, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int *info ); void LAPACK_zupmtr( char* side, char* uplo, char* trans, lapack_int* m, lapack_int* n, const lapack_complex_double* ap, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int *info ); void LAPACK_ssbtrd( char* vect, char* uplo, lapack_int* n, lapack_int* kd, float* ab, lapack_int* ldab, float* d, float* e, float* q, lapack_int* ldq, float* work, lapack_int *info ); void LAPACK_dsbtrd( char* vect, char* uplo, lapack_int* n, lapack_int* kd, double* ab, lapack_int* ldab, double* d, double* e, double* q, lapack_int* ldq, double* work, lapack_int *info ); void LAPACK_chbtrd( char* vect, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_float* ab, lapack_int* ldab, float* d, float* e, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* work, lapack_int *info ); void LAPACK_zhbtrd( char* vect, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_double* ab, lapack_int* ldab, double* d, double* e, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* work, lapack_int *info ); void LAPACK_ssterf( lapack_int* n, float* d, float* e, lapack_int *info ); void LAPACK_dsterf( lapack_int* n, double* d, double* e, lapack_int *info ); void LAPACK_ssteqr( char* compz, lapack_int* n, float* d, float* e, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dsteqr( char* compz, lapack_int* n, double* d, double* e, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_csteqr( char* compz, lapack_int* n, float* d, float* e, lapack_complex_float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_zsteqr( char* compz, lapack_int* n, double* d, double* e, lapack_complex_double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_sstemr( char* jobz, char* range, lapack_int* n, float* d, float* e, float* vl, float* vu, lapack_int* il, lapack_int* iu, lapack_int* m, float* w, float* z, lapack_int* ldz, lapack_int* nzc, lapack_int* isuppz, lapack_logical* tryrac, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dstemr( char* jobz, char* range, lapack_int* n, double* d, double* e, double* vl, double* vu, lapack_int* il, lapack_int* iu, lapack_int* m, double* w, double* z, lapack_int* ldz, lapack_int* nzc, lapack_int* isuppz, lapack_logical* tryrac, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_cstemr( char* jobz, char* range, lapack_int* n, float* d, float* e, float* vl, float* vu, lapack_int* il, lapack_int* iu, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_int* nzc, lapack_int* isuppz, lapack_logical* tryrac, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zstemr( char* jobz, char* range, lapack_int* n, double* d, double* e, double* vl, double* vu, lapack_int* il, lapack_int* iu, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_int* nzc, lapack_int* isuppz, lapack_logical* tryrac, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sstedc( char* compz, lapack_int* n, float* d, float* e, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dstedc( char* compz, lapack_int* n, double* d, double* e, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_cstedc( char* compz, lapack_int* n, float* d, float* e, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zstedc( char* compz, lapack_int* n, double* d, double* e, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sstegr( char* jobz, char* range, lapack_int* n, float* d, float* e, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, lapack_int* isuppz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dstegr( char* jobz, char* range, lapack_int* n, double* d, double* e, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, lapack_int* isuppz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_cstegr( char* jobz, char* range, lapack_int* n, float* d, float* e, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_int* isuppz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zstegr( char* jobz, char* range, lapack_int* n, double* d, double* e, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_int* isuppz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_spteqr( char* compz, lapack_int* n, float* d, float* e, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dpteqr( char* compz, lapack_int* n, double* d, double* e, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_cpteqr( char* compz, lapack_int* n, float* d, float* e, lapack_complex_float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_zpteqr( char* compz, lapack_int* n, double* d, double* e, lapack_complex_double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_sstebz( char* range, char* order, lapack_int* n, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, const float* d, const float* e, lapack_int* m, lapack_int* nsplit, float* w, lapack_int* iblock, lapack_int* isplit, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dstebz( char* range, char* order, lapack_int* n, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, const double* d, const double* e, lapack_int* m, lapack_int* nsplit, double* w, lapack_int* iblock, lapack_int* isplit, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_sstein( lapack_int* n, const float* d, const float* e, lapack_int* m, const float* w, const lapack_int* iblock, const lapack_int* isplit, float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifailv, lapack_int *info ); void LAPACK_dstein( lapack_int* n, const double* d, const double* e, lapack_int* m, const double* w, const lapack_int* iblock, const lapack_int* isplit, double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifailv, lapack_int *info ); void LAPACK_cstein( lapack_int* n, const float* d, const float* e, lapack_int* m, const float* w, const lapack_int* iblock, const lapack_int* isplit, lapack_complex_float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifailv, lapack_int *info ); void LAPACK_zstein( lapack_int* n, const double* d, const double* e, lapack_int* m, const double* w, const lapack_int* iblock, const lapack_int* isplit, lapack_complex_double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifailv, lapack_int *info ); void LAPACK_sdisna( char* job, lapack_int* m, lapack_int* n, const float* d, float* sep, lapack_int *info ); void LAPACK_ddisna( char* job, lapack_int* m, lapack_int* n, const double* d, double* sep, lapack_int *info ); void LAPACK_ssygst( lapack_int* itype, char* uplo, lapack_int* n, float* a, lapack_int* lda, const float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_dsygst( lapack_int* itype, char* uplo, lapack_int* n, double* a, lapack_int* lda, const double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_chegst( lapack_int* itype, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* b, lapack_int* ldb, lapack_int *info ); void LAPACK_zhegst( lapack_int* itype, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* b, lapack_int* ldb, lapack_int *info ); void LAPACK_sspgst( lapack_int* itype, char* uplo, lapack_int* n, float* ap, const float* bp, lapack_int *info ); void LAPACK_dspgst( lapack_int* itype, char* uplo, lapack_int* n, double* ap, const double* bp, lapack_int *info ); void LAPACK_chpgst( lapack_int* itype, char* uplo, lapack_int* n, lapack_complex_float* ap, const lapack_complex_float* bp, lapack_int *info ); void LAPACK_zhpgst( lapack_int* itype, char* uplo, lapack_int* n, lapack_complex_double* ap, const lapack_complex_double* bp, lapack_int *info ); void LAPACK_ssbgst( char* vect, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, float* ab, lapack_int* ldab, const float* bb, lapack_int* ldbb, float* x, lapack_int* ldx, float* work, lapack_int *info ); void LAPACK_dsbgst( char* vect, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, double* ab, lapack_int* ldab, const double* bb, lapack_int* ldbb, double* x, lapack_int* ldx, double* work, lapack_int *info ); void LAPACK_chbgst( char* vect, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_float* ab, lapack_int* ldab, const lapack_complex_float* bb, lapack_int* ldbb, lapack_complex_float* x, lapack_int* ldx, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhbgst( char* vect, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_double* ab, lapack_int* ldab, const lapack_complex_double* bb, lapack_int* ldbb, lapack_complex_double* x, lapack_int* ldx, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_spbstf( char* uplo, lapack_int* n, lapack_int* kb, float* bb, lapack_int* ldbb, lapack_int *info ); void LAPACK_dpbstf( char* uplo, lapack_int* n, lapack_int* kb, double* bb, lapack_int* ldbb, lapack_int *info ); void LAPACK_cpbstf( char* uplo, lapack_int* n, lapack_int* kb, lapack_complex_float* bb, lapack_int* ldbb, lapack_int *info ); void LAPACK_zpbstf( char* uplo, lapack_int* n, lapack_int* kb, lapack_complex_double* bb, lapack_int* ldbb, lapack_int *info ); void LAPACK_sgehrd( lapack_int* n, lapack_int* ilo, lapack_int* ihi, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgehrd( lapack_int* n, lapack_int* ilo, lapack_int* ihi, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgehrd( lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgehrd( lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sorghr( lapack_int* n, lapack_int* ilo, lapack_int* ihi, float* a, lapack_int* lda, const float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dorghr( lapack_int* n, lapack_int* ilo, lapack_int* ihi, double* a, lapack_int* lda, const double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sormhr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const float* a, lapack_int* lda, const float* tau, float* c, lapack_int* ldc, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dormhr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const double* a, lapack_int* lda, const double* tau, double* c, lapack_int* ldc, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunghr( lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunghr( lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cunmhr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zunmhr( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgebal( char* job, lapack_int* n, float* a, lapack_int* lda, lapack_int* ilo, lapack_int* ihi, float* scale, lapack_int *info ); void LAPACK_dgebal( char* job, lapack_int* n, double* a, lapack_int* lda, lapack_int* ilo, lapack_int* ihi, double* scale, lapack_int *info ); void LAPACK_cgebal( char* job, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* ilo, lapack_int* ihi, float* scale, lapack_int *info ); void LAPACK_zgebal( char* job, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* ilo, lapack_int* ihi, double* scale, lapack_int *info ); void LAPACK_sgebak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const float* scale, lapack_int* m, float* v, lapack_int* ldv, lapack_int *info ); void LAPACK_dgebak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const double* scale, lapack_int* m, double* v, lapack_int* ldv, lapack_int *info ); void LAPACK_cgebak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const float* scale, lapack_int* m, lapack_complex_float* v, lapack_int* ldv, lapack_int *info ); void LAPACK_zgebak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const double* scale, lapack_int* m, lapack_complex_double* v, lapack_int* ldv, lapack_int *info ); void LAPACK_shseqr( char* job, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, float* h, lapack_int* ldh, float* wr, float* wi, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dhseqr( char* job, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, double* h, lapack_int* ldh, double* wr, double* wi, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_chseqr( char* job, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_float* h, lapack_int* ldh, lapack_complex_float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zhseqr( char* job, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_double* h, lapack_int* ldh, lapack_complex_double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_shsein( char* job, char* eigsrc, char* initv, lapack_logical* select, lapack_int* n, const float* h, lapack_int* ldh, float* wr, const float* wi, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, float* work, lapack_int* ifaill, lapack_int* ifailr, lapack_int *info ); void LAPACK_dhsein( char* job, char* eigsrc, char* initv, lapack_logical* select, lapack_int* n, const double* h, lapack_int* ldh, double* wr, const double* wi, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, double* work, lapack_int* ifaill, lapack_int* ifailr, lapack_int *info ); void LAPACK_chsein( char* job, char* eigsrc, char* initv, const lapack_logical* select, lapack_int* n, const lapack_complex_float* h, lapack_int* ldh, lapack_complex_float* w, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, lapack_complex_float* work, float* rwork, lapack_int* ifaill, lapack_int* ifailr, lapack_int *info ); void LAPACK_zhsein( char* job, char* eigsrc, char* initv, const lapack_logical* select, lapack_int* n, const lapack_complex_double* h, lapack_int* ldh, lapack_complex_double* w, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, lapack_complex_double* work, double* rwork, lapack_int* ifaill, lapack_int* ifailr, lapack_int *info ); void LAPACK_strevc( char* side, char* howmny, lapack_logical* select, lapack_int* n, const float* t, lapack_int* ldt, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, float* work, lapack_int *info ); void LAPACK_dtrevc( char* side, char* howmny, lapack_logical* select, lapack_int* n, const double* t, lapack_int* ldt, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, double* work, lapack_int *info ); void LAPACK_ctrevc( char* side, char* howmny, const lapack_logical* select, lapack_int* n, lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztrevc( char* side, char* howmny, const lapack_logical* select, lapack_int* n, lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_strsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const float* t, lapack_int* ldt, const float* vl, lapack_int* ldvl, const float* vr, lapack_int* ldvr, float* s, float* sep, lapack_int* mm, lapack_int* m, float* work, lapack_int* ldwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dtrsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const double* t, lapack_int* ldt, const double* vl, lapack_int* ldvl, const double* vr, lapack_int* ldvr, double* s, double* sep, lapack_int* mm, lapack_int* m, double* work, lapack_int* ldwork, lapack_int* iwork, lapack_int *info ); void LAPACK_ctrsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const lapack_complex_float* t, lapack_int* ldt, const lapack_complex_float* vl, lapack_int* ldvl, const lapack_complex_float* vr, lapack_int* ldvr, float* s, float* sep, lapack_int* mm, lapack_int* m, lapack_complex_float* work, lapack_int* ldwork, float* rwork, lapack_int *info ); void LAPACK_ztrsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const lapack_complex_double* t, lapack_int* ldt, const lapack_complex_double* vl, lapack_int* ldvl, const lapack_complex_double* vr, lapack_int* ldvr, double* s, double* sep, lapack_int* mm, lapack_int* m, lapack_complex_double* work, lapack_int* ldwork, double* rwork, lapack_int *info ); void LAPACK_strexc( char* compq, lapack_int* n, float* t, lapack_int* ldt, float* q, lapack_int* ldq, lapack_int* ifst, lapack_int* ilst, float* work, lapack_int *info ); void LAPACK_dtrexc( char* compq, lapack_int* n, double* t, lapack_int* ldt, double* q, lapack_int* ldq, lapack_int* ifst, lapack_int* ilst, double* work, lapack_int *info ); void LAPACK_ctrexc( char* compq, lapack_int* n, lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* q, lapack_int* ldq, lapack_int* ifst, lapack_int* ilst, lapack_int *info ); void LAPACK_ztrexc( char* compq, lapack_int* n, lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* q, lapack_int* ldq, lapack_int* ifst, lapack_int* ilst, lapack_int *info ); void LAPACK_strsen( char* job, char* compq, const lapack_logical* select, lapack_int* n, float* t, lapack_int* ldt, float* q, lapack_int* ldq, float* wr, float* wi, lapack_int* m, float* s, float* sep, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dtrsen( char* job, char* compq, const lapack_logical* select, lapack_int* n, double* t, lapack_int* ldt, double* q, lapack_int* ldq, double* wr, double* wi, lapack_int* m, double* s, double* sep, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ctrsen( char* job, char* compq, const lapack_logical* select, lapack_int* n, lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* w, lapack_int* m, float* s, float* sep, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ztrsen( char* job, char* compq, const lapack_logical* select, lapack_int* n, lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* w, lapack_int* m, double* s, double* sep, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_strsyl( char* trana, char* tranb, lapack_int* isgn, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, const float* b, lapack_int* ldb, float* c, lapack_int* ldc, float* scale, lapack_int *info ); void LAPACK_dtrsyl( char* trana, char* tranb, lapack_int* isgn, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, const double* b, lapack_int* ldb, double* c, lapack_int* ldc, double* scale, lapack_int *info ); void LAPACK_ctrsyl( char* trana, char* tranb, lapack_int* isgn, lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* c, lapack_int* ldc, float* scale, lapack_int *info ); void LAPACK_ztrsyl( char* trana, char* tranb, lapack_int* isgn, lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* c, lapack_int* ldc, double* scale, lapack_int *info ); void LAPACK_sgghrd( char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* q, lapack_int* ldq, float* z, lapack_int* ldz, lapack_int *info ); void LAPACK_dgghrd( char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* q, lapack_int* ldq, double* z, lapack_int* ldz, lapack_int *info ); void LAPACK_cgghrd( char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* z, lapack_int* ldz, lapack_int *info ); void LAPACK_zgghrd( char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* z, lapack_int* ldz, lapack_int *info ); void LAPACK_sggbal( char* job, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* work, lapack_int *info ); void LAPACK_dggbal( char* job, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* work, lapack_int *info ); void LAPACK_cggbal( char* job, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* work, lapack_int *info ); void LAPACK_zggbal( char* job, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* work, lapack_int *info ); void LAPACK_sggbak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const float* lscale, const float* rscale, lapack_int* m, float* v, lapack_int* ldv, lapack_int *info ); void LAPACK_dggbak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const double* lscale, const double* rscale, lapack_int* m, double* v, lapack_int* ldv, lapack_int *info ); void LAPACK_cggbak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const float* lscale, const float* rscale, lapack_int* m, lapack_complex_float* v, lapack_int* ldv, lapack_int *info ); void LAPACK_zggbak( char* job, char* side, lapack_int* n, lapack_int* ilo, lapack_int* ihi, const double* lscale, const double* rscale, lapack_int* m, lapack_complex_double* v, lapack_int* ldv, lapack_int *info ); void LAPACK_shgeqz( char* job, char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, float* h, lapack_int* ldh, float* t, lapack_int* ldt, float* alphar, float* alphai, float* beta, float* q, lapack_int* ldq, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dhgeqz( char* job, char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, double* h, lapack_int* ldh, double* t, lapack_int* ldt, double* alphar, double* alphai, double* beta, double* q, lapack_int* ldq, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_chgeqz( char* job, char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_float* h, lapack_int* ldh, lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zhgeqz( char* job, char* compq, char* compz, lapack_int* n, lapack_int* ilo, lapack_int* ihi, lapack_complex_double* h, lapack_int* ldh, lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_stgevc( char* side, char* howmny, const lapack_logical* select, lapack_int* n, const float* s, lapack_int* lds, const float* p, lapack_int* ldp, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, float* work, lapack_int *info ); void LAPACK_dtgevc( char* side, char* howmny, const lapack_logical* select, lapack_int* n, const double* s, lapack_int* lds, const double* p, lapack_int* ldp, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, double* work, lapack_int *info ); void LAPACK_ctgevc( char* side, char* howmny, const lapack_logical* select, lapack_int* n, const lapack_complex_float* s, lapack_int* lds, const lapack_complex_float* p, lapack_int* ldp, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_ztgevc( char* side, char* howmny, const lapack_logical* select, lapack_int* n, const lapack_complex_double* s, lapack_int* lds, const lapack_complex_double* p, lapack_int* ldp, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_int* mm, lapack_int* m, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_stgexc( lapack_logical* wantq, lapack_logical* wantz, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* q, lapack_int* ldq, float* z, lapack_int* ldz, lapack_int* ifst, lapack_int* ilst, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dtgexc( lapack_logical* wantq, lapack_logical* wantz, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* q, lapack_int* ldq, double* z, lapack_int* ldz, lapack_int* ifst, lapack_int* ilst, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ctgexc( lapack_logical* wantq, lapack_logical* wantz, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* z, lapack_int* ldz, lapack_int* ifst, lapack_int* ilst, lapack_int *info ); void LAPACK_ztgexc( lapack_logical* wantq, lapack_logical* wantz, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* z, lapack_int* ldz, lapack_int* ifst, lapack_int* ilst, lapack_int *info ); void LAPACK_stgsen( lapack_int* ijob, lapack_logical* wantq, lapack_logical* wantz, const lapack_logical* select, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* alphar, float* alphai, float* beta, float* q, lapack_int* ldq, float* z, lapack_int* ldz, lapack_int* m, float* pl, float* pr, float* dif, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dtgsen( lapack_int* ijob, lapack_logical* wantq, lapack_logical* wantz, const lapack_logical* select, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* alphar, double* alphai, double* beta, double* q, lapack_int* ldq, double* z, lapack_int* ldz, lapack_int* m, double* pl, double* pr, double* dif, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ctgsen( lapack_int* ijob, lapack_logical* wantq, lapack_logical* wantz, const lapack_logical* select, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* z, lapack_int* ldz, lapack_int* m, float* pl, float* pr, float* dif, lapack_complex_float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ztgsen( lapack_int* ijob, lapack_logical* wantq, lapack_logical* wantz, const lapack_logical* select, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* z, lapack_int* ldz, lapack_int* m, double* pl, double* pr, double* dif, lapack_complex_double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_stgsyl( char* trans, lapack_int* ijob, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, const float* b, lapack_int* ldb, float* c, lapack_int* ldc, const float* d, lapack_int* ldd, const float* e, lapack_int* lde, float* f, lapack_int* ldf, float* scale, float* dif, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dtgsyl( char* trans, lapack_int* ijob, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, const double* b, lapack_int* ldb, double* c, lapack_int* ldc, const double* d, lapack_int* ldd, const double* e, lapack_int* lde, double* f, lapack_int* ldf, double* scale, double* dif, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_ctgsyl( char* trans, lapack_int* ijob, lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* c, lapack_int* ldc, const lapack_complex_float* d, lapack_int* ldd, const lapack_complex_float* e, lapack_int* lde, lapack_complex_float* f, lapack_int* ldf, float* scale, float* dif, lapack_complex_float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_ztgsyl( char* trans, lapack_int* ijob, lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* c, lapack_int* ldc, const lapack_complex_double* d, lapack_int* ldd, const lapack_complex_double* e, lapack_int* lde, lapack_complex_double* f, lapack_int* ldf, double* scale, double* dif, lapack_complex_double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_stgsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const float* a, lapack_int* lda, const float* b, lapack_int* ldb, const float* vl, lapack_int* ldvl, const float* vr, lapack_int* ldvr, float* s, float* dif, lapack_int* mm, lapack_int* m, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dtgsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const double* a, lapack_int* lda, const double* b, lapack_int* ldb, const double* vl, lapack_int* ldvl, const double* vr, lapack_int* ldvr, double* s, double* dif, lapack_int* mm, lapack_int* m, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_ctgsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, const lapack_complex_float* b, lapack_int* ldb, const lapack_complex_float* vl, lapack_int* ldvl, const lapack_complex_float* vr, lapack_int* ldvr, float* s, float* dif, lapack_int* mm, lapack_int* m, lapack_complex_float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_ztgsna( char* job, char* howmny, const lapack_logical* select, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, const lapack_complex_double* b, lapack_int* ldb, const lapack_complex_double* vl, lapack_int* ldvl, const lapack_complex_double* vr, lapack_int* ldvr, double* s, double* dif, lapack_int* mm, lapack_int* m, lapack_complex_double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_sggsvp( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* tola, float* tolb, lapack_int* k, lapack_int* l, float* u, lapack_int* ldu, float* v, lapack_int* ldv, float* q, lapack_int* ldq, lapack_int* iwork, float* tau, float* work, lapack_int *info ); void LAPACK_dggsvp( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* tola, double* tolb, lapack_int* k, lapack_int* l, double* u, lapack_int* ldu, double* v, lapack_int* ldv, double* q, lapack_int* ldq, lapack_int* iwork, double* tau, double* work, lapack_int *info ); void LAPACK_cggsvp( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* tola, float* tolb, lapack_int* k, lapack_int* l, lapack_complex_float* u, lapack_int* ldu, lapack_complex_float* v, lapack_int* ldv, lapack_complex_float* q, lapack_int* ldq, lapack_int* iwork, float* rwork, lapack_complex_float* tau, lapack_complex_float* work, lapack_int *info ); void LAPACK_zggsvp( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* tola, double* tolb, lapack_int* k, lapack_int* l, lapack_complex_double* u, lapack_int* ldu, lapack_complex_double* v, lapack_int* ldv, lapack_complex_double* q, lapack_int* ldq, lapack_int* iwork, double* rwork, lapack_complex_double* tau, lapack_complex_double* work, lapack_int *info ); void LAPACK_stgsja( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, lapack_int* k, lapack_int* l, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* tola, float* tolb, float* alpha, float* beta, float* u, lapack_int* ldu, float* v, lapack_int* ldv, float* q, lapack_int* ldq, float* work, lapack_int* ncycle, lapack_int *info ); void LAPACK_dtgsja( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, lapack_int* k, lapack_int* l, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* tola, double* tolb, double* alpha, double* beta, double* u, lapack_int* ldu, double* v, lapack_int* ldv, double* q, lapack_int* ldq, double* work, lapack_int* ncycle, lapack_int *info ); void LAPACK_ctgsja( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, lapack_int* k, lapack_int* l, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* tola, float* tolb, float* alpha, float* beta, lapack_complex_float* u, lapack_int* ldu, lapack_complex_float* v, lapack_int* ldv, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* work, lapack_int* ncycle, lapack_int *info ); void LAPACK_ztgsja( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* p, lapack_int* n, lapack_int* k, lapack_int* l, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* tola, double* tolb, double* alpha, double* beta, lapack_complex_double* u, lapack_int* ldu, lapack_complex_double* v, lapack_int* ldv, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* work, lapack_int* ncycle, lapack_int *info ); void LAPACK_sgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgels( char* trans, lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgelsy( lapack_int* m, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int* jpvt, float* rcond, lapack_int* rank, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgelsy( lapack_int* m, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int* jpvt, double* rcond, lapack_int* rank, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgelsy( lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int* jpvt, float* rcond, lapack_int* rank, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zgelsy( lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int* jpvt, double* rcond, lapack_int* rank, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sgelss( lapack_int* m, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* s, float* rcond, lapack_int* rank, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgelss( lapack_int* m, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* s, double* rcond, lapack_int* rank, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgelss( lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* s, float* rcond, lapack_int* rank, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zgelss( lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* s, double* rcond, lapack_int* rank, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sgelsd( lapack_int* m, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* s, float* rcond, lapack_int* rank, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dgelsd( lapack_int* m, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* s, double* rcond, lapack_int* rank, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_cgelsd( lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* s, float* rcond, lapack_int* rank, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* iwork, lapack_int *info ); void LAPACK_zgelsd( lapack_int* m, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* s, double* rcond, lapack_int* rank, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* iwork, lapack_int *info ); void LAPACK_sgglse( lapack_int* m, lapack_int* n, lapack_int* p, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* c, float* d, float* x, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgglse( lapack_int* m, lapack_int* n, lapack_int* p, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* c, double* d, double* x, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgglse( lapack_int* m, lapack_int* n, lapack_int* p, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* c, lapack_complex_float* d, lapack_complex_float* x, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgglse( lapack_int* m, lapack_int* n, lapack_int* p, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* c, lapack_complex_double* d, lapack_complex_double* x, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sggglm( lapack_int* n, lapack_int* m, lapack_int* p, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* d, float* x, float* y, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dggglm( lapack_int* n, lapack_int* m, lapack_int* p, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* d, double* x, double* y, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cggglm( lapack_int* n, lapack_int* m, lapack_int* p, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* d, lapack_complex_float* x, lapack_complex_float* y, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zggglm( lapack_int* n, lapack_int* m, lapack_int* p, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* d, lapack_complex_double* x, lapack_complex_double* y, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_ssyev( char* jobz, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* w, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dsyev( char* jobz, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* w, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cheev( char* jobz, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* w, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zheev( char* jobz, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* w, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_ssyevd( char* jobz, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* w, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dsyevd( char* jobz, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* w, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_cheevd( char* jobz, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* w, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zheevd( char* jobz, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* w, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ssyevx( char* jobz, char* range, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dsyevx( char* jobz, char* range, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_cheevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_zheevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_ssyevr( char* jobz, char* range, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, lapack_int* isuppz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dsyevr( char* jobz, char* range, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, lapack_int* isuppz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_cheevr( char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_int* isuppz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zheevr( char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_int* isuppz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sspev( char* jobz, char* uplo, lapack_int* n, float* ap, float* w, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dspev( char* jobz, char* uplo, lapack_int* n, double* ap, double* w, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_chpev( char* jobz, char* uplo, lapack_int* n, lapack_complex_float* ap, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhpev( char* jobz, char* uplo, lapack_int* n, lapack_complex_double* ap, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sspevd( char* jobz, char* uplo, lapack_int* n, float* ap, float* w, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dspevd( char* jobz, char* uplo, lapack_int* n, double* ap, double* w, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_chpevd( char* jobz, char* uplo, lapack_int* n, lapack_complex_float* ap, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zhpevd( char* jobz, char* uplo, lapack_int* n, lapack_complex_double* ap, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sspevx( char* jobz, char* range, char* uplo, lapack_int* n, float* ap, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dspevx( char* jobz, char* range, char* uplo, lapack_int* n, double* ap, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_chpevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_float* ap, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_zhpevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_double* ap, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_ssbev( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, float* ab, lapack_int* ldab, float* w, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dsbev( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, double* ab, lapack_int* ldab, double* w, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_chbev( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_float* ab, lapack_int* ldab, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhbev( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_double* ab, lapack_int* ldab, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_ssbevd( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, float* ab, lapack_int* ldab, float* w, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dsbevd( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, double* ab, lapack_int* ldab, double* w, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_chbevd( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_float* ab, lapack_int* ldab, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zhbevd( char* jobz, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_double* ab, lapack_int* ldab, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ssbevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* kd, float* ab, lapack_int* ldab, float* q, lapack_int* ldq, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dsbevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* kd, double* ab, lapack_int* ldab, double* q, lapack_int* ldq, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_chbevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* q, lapack_int* ldq, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_zhbevx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* kd, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* q, lapack_int* ldq, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_sstev( char* jobz, lapack_int* n, float* d, float* e, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dstev( char* jobz, lapack_int* n, double* d, double* e, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_sstevd( char* jobz, lapack_int* n, float* d, float* e, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dstevd( char* jobz, lapack_int* n, double* d, double* e, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sstevx( char* jobz, char* range, lapack_int* n, float* d, float* e, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dstevx( char* jobz, char* range, lapack_int* n, double* d, double* e, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_sstevr( char* jobz, char* range, lapack_int* n, float* d, float* e, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, lapack_int* isuppz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dstevr( char* jobz, char* range, lapack_int* n, double* d, double* e, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, lapack_int* isuppz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sgees( char* jobvs, char* sort, LAPACK_S_SELECT2 select, lapack_int* n, float* a, lapack_int* lda, lapack_int* sdim, float* wr, float* wi, float* vs, lapack_int* ldvs, float* work, lapack_int* lwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_dgees( char* jobvs, char* sort, LAPACK_D_SELECT2 select, lapack_int* n, double* a, lapack_int* lda, lapack_int* sdim, double* wr, double* wi, double* vs, lapack_int* ldvs, double* work, lapack_int* lwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_cgees( char* jobvs, char* sort, LAPACK_C_SELECT1 select, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* sdim, lapack_complex_float* w, lapack_complex_float* vs, lapack_int* ldvs, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_zgees( char* jobvs, char* sort, LAPACK_Z_SELECT1 select, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* sdim, lapack_complex_double* w, lapack_complex_double* vs, lapack_int* ldvs, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_sgeesx( char* jobvs, char* sort, LAPACK_S_SELECT2 select, char* sense, lapack_int* n, float* a, lapack_int* lda, lapack_int* sdim, float* wr, float* wi, float* vs, lapack_int* ldvs, float* rconde, float* rcondv, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_dgeesx( char* jobvs, char* sort, LAPACK_D_SELECT2 select, char* sense, lapack_int* n, double* a, lapack_int* lda, lapack_int* sdim, double* wr, double* wi, double* vs, lapack_int* ldvs, double* rconde, double* rcondv, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_cgeesx( char* jobvs, char* sort, LAPACK_C_SELECT1 select, char* sense, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* sdim, lapack_complex_float* w, lapack_complex_float* vs, lapack_int* ldvs, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_zgeesx( char* jobvs, char* sort, LAPACK_Z_SELECT1 select, char* sense, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* sdim, lapack_complex_double* w, lapack_complex_double* vs, lapack_int* ldvs, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_sgeev( char* jobvl, char* jobvr, lapack_int* n, float* a, lapack_int* lda, float* wr, float* wi, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgeev( char* jobvl, char* jobvr, lapack_int* n, double* a, lapack_int* lda, double* wr, double* wi, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgeev( char* jobvl, char* jobvr, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* w, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zgeev( char* jobvl, char* jobvr, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* w, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sgeevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, float* a, lapack_int* lda, float* wr, float* wi, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dgeevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, double* a, lapack_int* lda, double* wr, double* wi, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_cgeevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* w, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, float* scale, float* abnrm, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zgeevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* w, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, double* scale, double* abnrm, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sgesvd( char* jobu, char* jobvt, lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* s, float* u, lapack_int* ldu, float* vt, lapack_int* ldvt, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgesvd( char* jobu, char* jobvt, lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* s, double* u, lapack_int* ldu, double* vt, lapack_int* ldvt, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgesvd( char* jobu, char* jobvt, lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* s, lapack_complex_float* u, lapack_int* ldu, lapack_complex_float* vt, lapack_int* ldvt, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zgesvd( char* jobu, char* jobvt, lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* s, lapack_complex_double* u, lapack_int* ldu, lapack_complex_double* vt, lapack_int* ldvt, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sgesdd( char* jobz, lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* s, float* u, lapack_int* ldu, float* vt, lapack_int* ldvt, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dgesdd( char* jobz, lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* s, double* u, lapack_int* ldu, double* vt, lapack_int* ldvt, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_cgesdd( char* jobz, lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, float* s, lapack_complex_float* u, lapack_int* ldu, lapack_complex_float* vt, lapack_int* ldvt, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* iwork, lapack_int *info ); void LAPACK_zgesdd( char* jobz, lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, double* s, lapack_complex_double* u, lapack_int* ldu, lapack_complex_double* vt, lapack_int* ldvt, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dgejsv( char* joba, char* jobu, char* jobv, char* jobr, char* jobt, char* jobp, lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* sva, double* u, lapack_int* ldu, double* v, lapack_int* ldv, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_sgejsv( char* joba, char* jobu, char* jobv, char* jobr, char* jobt, char* jobp, lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* sva, float* u, lapack_int* ldu, float* v, lapack_int* ldv, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int *info ); void LAPACK_dgesvj( char* joba, char* jobu, char* jobv, lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* sva, lapack_int* mv, double* v, lapack_int* ldv, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sgesvj( char* joba, char* jobu, char* jobv, lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* sva, lapack_int* mv, float* v, lapack_int* ldv, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_sggsvd( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* n, lapack_int* p, lapack_int* k, lapack_int* l, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* alpha, float* beta, float* u, lapack_int* ldu, float* v, lapack_int* ldv, float* q, lapack_int* ldq, float* work, lapack_int* iwork, lapack_int *info ); void LAPACK_dggsvd( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* n, lapack_int* p, lapack_int* k, lapack_int* l, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* alpha, double* beta, double* u, lapack_int* ldu, double* v, lapack_int* ldv, double* q, lapack_int* ldq, double* work, lapack_int* iwork, lapack_int *info ); void LAPACK_cggsvd( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* n, lapack_int* p, lapack_int* k, lapack_int* l, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* alpha, float* beta, lapack_complex_float* u, lapack_int* ldu, lapack_complex_float* v, lapack_int* ldv, lapack_complex_float* q, lapack_int* ldq, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int *info ); void LAPACK_zggsvd( char* jobu, char* jobv, char* jobq, lapack_int* m, lapack_int* n, lapack_int* p, lapack_int* k, lapack_int* l, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* alpha, double* beta, lapack_complex_double* u, lapack_int* ldu, lapack_complex_double* v, lapack_int* ldv, lapack_complex_double* q, lapack_int* ldq, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int *info ); void LAPACK_ssygv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* w, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dsygv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* w, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_chegv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* w, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zhegv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* w, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_ssygvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* w, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dsygvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* w, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_chegvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* w, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zhegvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* w, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ssygvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dsygvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_chegvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_zhegvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_sspgv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, float* ap, float* bp, float* w, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dspgv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, double* ap, double* bp, double* w, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_chpgv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_complex_float* bp, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhpgv( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_complex_double* bp, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_sspgvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, float* ap, float* bp, float* w, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dspgvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, double* ap, double* bp, double* w, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_chpgvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_complex_float* bp, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zhpgvd( lapack_int* itype, char* jobz, char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_complex_double* bp, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_sspgvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, float* ap, float* bp, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dspgvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, double* ap, double* bp, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_chpgvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_float* ap, lapack_complex_float* bp, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_zhpgvx( lapack_int* itype, char* jobz, char* range, char* uplo, lapack_int* n, lapack_complex_double* ap, lapack_complex_double* bp, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_ssbgv( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, float* ab, lapack_int* ldab, float* bb, lapack_int* ldbb, float* w, float* z, lapack_int* ldz, float* work, lapack_int *info ); void LAPACK_dsbgv( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, double* ab, lapack_int* ldab, double* bb, lapack_int* ldbb, double* w, double* z, lapack_int* ldz, double* work, lapack_int *info ); void LAPACK_chbgv( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* bb, lapack_int* ldbb, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int *info ); void LAPACK_zhbgv( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* bb, lapack_int* ldbb, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int *info ); void LAPACK_ssbgvd( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, float* ab, lapack_int* ldab, float* bb, lapack_int* ldbb, float* w, float* z, lapack_int* ldz, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_dsbgvd( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, double* ab, lapack_int* ldab, double* bb, lapack_int* ldbb, double* w, double* z, lapack_int* ldz, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_chbgvd( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* bb, lapack_int* ldbb, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_zhbgvd( char* jobz, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* bb, lapack_int* ldbb, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork, lapack_int* liwork, lapack_int *info ); void LAPACK_ssbgvx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, float* ab, lapack_int* ldab, float* bb, lapack_int* ldbb, float* q, lapack_int* ldq, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, float* z, lapack_int* ldz, float* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_dsbgvx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, double* ab, lapack_int* ldab, double* bb, lapack_int* ldbb, double* q, lapack_int* ldq, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, double* z, lapack_int* ldz, double* work, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_chbgvx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_float* ab, lapack_int* ldab, lapack_complex_float* bb, lapack_int* ldbb, lapack_complex_float* q, lapack_int* ldq, float* vl, float* vu, lapack_int* il, lapack_int* iu, float* abstol, lapack_int* m, float* w, lapack_complex_float* z, lapack_int* ldz, lapack_complex_float* work, float* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_zhbgvx( char* jobz, char* range, char* uplo, lapack_int* n, lapack_int* ka, lapack_int* kb, lapack_complex_double* ab, lapack_int* ldab, lapack_complex_double* bb, lapack_int* ldbb, lapack_complex_double* q, lapack_int* ldq, double* vl, double* vu, lapack_int* il, lapack_int* iu, double* abstol, lapack_int* m, double* w, lapack_complex_double* z, lapack_int* ldz, lapack_complex_double* work, double* rwork, lapack_int* iwork, lapack_int* ifail, lapack_int *info ); void LAPACK_sgges( char* jobvsl, char* jobvsr, char* sort, LAPACK_S_SELECT3 selctg, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, lapack_int* ldvsl, float* vsr, lapack_int* ldvsr, float* work, lapack_int* lwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_dgges( char* jobvsl, char* jobvsr, char* sort, LAPACK_D_SELECT3 selctg, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, lapack_int* ldvsl, double* vsr, lapack_int* ldvsr, double* work, lapack_int* lwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_cgges( char* jobvsl, char* jobvsr, char* sort, LAPACK_C_SELECT2 selctg, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int* sdim, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vsl, lapack_int* ldvsl, lapack_complex_float* vsr, lapack_int* ldvsr, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_zgges( char* jobvsl, char* jobvsr, char* sort, LAPACK_Z_SELECT2 selctg, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int* sdim, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vsl, lapack_int* ldvsl, lapack_complex_double* vsr, lapack_int* ldvsr, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_sggesx( char* jobvsl, char* jobvsr, char* sort, LAPACK_S_SELECT3 selctg, char* sense, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, lapack_int* sdim, float* alphar, float* alphai, float* beta, float* vsl, lapack_int* ldvsl, float* vsr, lapack_int* ldvsr, float* rconde, float* rcondv, float* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_dggesx( char* jobvsl, char* jobvsr, char* sort, LAPACK_D_SELECT3 selctg, char* sense, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, lapack_int* sdim, double* alphar, double* alphai, double* beta, double* vsl, lapack_int* ldvsl, double* vsr, lapack_int* ldvsr, double* rconde, double* rcondv, double* work, lapack_int* lwork, lapack_int* iwork, lapack_int* liwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_cggesx( char* jobvsl, char* jobvsr, char* sort, LAPACK_C_SELECT2 selctg, char* sense, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_int* sdim, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vsl, lapack_int* ldvsl, lapack_complex_float* vsr, lapack_int* ldvsr, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* iwork, lapack_int* liwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_zggesx( char* jobvsl, char* jobvsr, char* sort, LAPACK_Z_SELECT2 selctg, char* sense, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_int* sdim, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vsl, lapack_int* ldvsl, lapack_complex_double* vsr, lapack_int* ldvsr, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* iwork, lapack_int* liwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_sggev( char* jobvl, char* jobvr, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* alphar, float* alphai, float* beta, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dggev( char* jobvl, char* jobvr, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* alphar, double* alphai, double* beta, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cggev( char* jobvl, char* jobvr, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int *info ); void LAPACK_zggev( char* jobvl, char* jobvr, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int *info ); void LAPACK_sggevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* alphar, float* alphai, float* beta, float* vl, lapack_int* ldvl, float* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* abnrm, float* bbnrm, float* rconde, float* rcondv, float* work, lapack_int* lwork, lapack_int* iwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_dggevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* alphar, double* alphai, double* beta, double* vl, lapack_int* ldvl, double* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* abnrm, double* bbnrm, double* rconde, double* rcondv, double* work, lapack_int* lwork, lapack_int* iwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_cggevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* vl, lapack_int* ldvl, lapack_complex_float* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, float* lscale, float* rscale, float* abnrm, float* bbnrm, float* rconde, float* rcondv, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* iwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_zggevx( char* balanc, char* jobvl, char* jobvr, char* sense, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* vl, lapack_int* ldvl, lapack_complex_double* vr, lapack_int* ldvr, lapack_int* ilo, lapack_int* ihi, double* lscale, double* rscale, double* abnrm, double* bbnrm, double* rconde, double* rcondv, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* iwork, lapack_logical* bwork, lapack_int *info ); void LAPACK_dsfrk( char* transr, char* uplo, char* trans, lapack_int* n, lapack_int* k, double* alpha, const double* a, lapack_int* lda, double* beta, double* c ); void LAPACK_ssfrk( char* transr, char* uplo, char* trans, lapack_int* n, lapack_int* k, float* alpha, const float* a, lapack_int* lda, float* beta, float* c ); void LAPACK_zhfrk( char* transr, char* uplo, char* trans, lapack_int* n, lapack_int* k, double* alpha, const lapack_complex_double* a, lapack_int* lda, double* beta, lapack_complex_double* c ); void LAPACK_chfrk( char* transr, char* uplo, char* trans, lapack_int* n, lapack_int* k, float* alpha, const lapack_complex_float* a, lapack_int* lda, float* beta, lapack_complex_float* c ); void LAPACK_dtfsm( char* transr, char* side, char* uplo, char* trans, char* diag, lapack_int* m, lapack_int* n, double* alpha, const double* a, double* b, lapack_int* ldb ); void LAPACK_stfsm( char* transr, char* side, char* uplo, char* trans, char* diag, lapack_int* m, lapack_int* n, float* alpha, const float* a, float* b, lapack_int* ldb ); void LAPACK_ztfsm( char* transr, char* side, char* uplo, char* trans, char* diag, lapack_int* m, lapack_int* n, lapack_complex_double* alpha, const lapack_complex_double* a, lapack_complex_double* b, lapack_int* ldb ); void LAPACK_ctfsm( char* transr, char* side, char* uplo, char* trans, char* diag, lapack_int* m, lapack_int* n, lapack_complex_float* alpha, const lapack_complex_float* a, lapack_complex_float* b, lapack_int* ldb ); void LAPACK_dtfttp( char* transr, char* uplo, lapack_int* n, const double* arf, double* ap, lapack_int *info ); void LAPACK_stfttp( char* transr, char* uplo, lapack_int* n, const float* arf, float* ap, lapack_int *info ); void LAPACK_ztfttp( char* transr, char* uplo, lapack_int* n, const lapack_complex_double* arf, lapack_complex_double* ap, lapack_int *info ); void LAPACK_ctfttp( char* transr, char* uplo, lapack_int* n, const lapack_complex_float* arf, lapack_complex_float* ap, lapack_int *info ); void LAPACK_dtfttr( char* transr, char* uplo, lapack_int* n, const double* arf, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_stfttr( char* transr, char* uplo, lapack_int* n, const float* arf, float* a, lapack_int* lda, lapack_int *info ); void LAPACK_ztfttr( char* transr, char* uplo, lapack_int* n, const lapack_complex_double* arf, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_ctfttr( char* transr, char* uplo, lapack_int* n, const lapack_complex_float* arf, lapack_complex_float* a, lapack_int* lda, lapack_int *info ); void LAPACK_dtpttf( char* transr, char* uplo, lapack_int* n, const double* ap, double* arf, lapack_int *info ); void LAPACK_stpttf( char* transr, char* uplo, lapack_int* n, const float* ap, float* arf, lapack_int *info ); void LAPACK_ztpttf( char* transr, char* uplo, lapack_int* n, const lapack_complex_double* ap, lapack_complex_double* arf, lapack_int *info ); void LAPACK_ctpttf( char* transr, char* uplo, lapack_int* n, const lapack_complex_float* ap, lapack_complex_float* arf, lapack_int *info ); void LAPACK_dtpttr( char* uplo, lapack_int* n, const double* ap, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_stpttr( char* uplo, lapack_int* n, const float* ap, float* a, lapack_int* lda, lapack_int *info ); void LAPACK_ztpttr( char* uplo, lapack_int* n, const lapack_complex_double* ap, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_ctpttr( char* uplo, lapack_int* n, const lapack_complex_float* ap, lapack_complex_float* a, lapack_int* lda, lapack_int *info ); void LAPACK_dtrttf( char* transr, char* uplo, lapack_int* n, const double* a, lapack_int* lda, double* arf, lapack_int *info ); void LAPACK_strttf( char* transr, char* uplo, lapack_int* n, const float* a, lapack_int* lda, float* arf, lapack_int *info ); void LAPACK_ztrttf( char* transr, char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* arf, lapack_int *info ); void LAPACK_ctrttf( char* transr, char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* arf, lapack_int *info ); void LAPACK_dtrttp( char* uplo, lapack_int* n, const double* a, lapack_int* lda, double* ap, lapack_int *info ); void LAPACK_strttp( char* uplo, lapack_int* n, const float* a, lapack_int* lda, float* ap, lapack_int *info ); void LAPACK_ztrttp( char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* ap, lapack_int *info ); void LAPACK_ctrttp( char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* ap, lapack_int *info ); void LAPACK_sgeqrfp( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dgeqrfp( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_cgeqrfp( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zgeqrfp( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_clacgv( lapack_int* n, lapack_complex_float* x, lapack_int* incx ); void LAPACK_zlacgv( lapack_int* n, lapack_complex_double* x, lapack_int* incx ); void LAPACK_slarnv( lapack_int* idist, lapack_int* iseed, lapack_int* n, float* x ); void LAPACK_dlarnv( lapack_int* idist, lapack_int* iseed, lapack_int* n, double* x ); void LAPACK_clarnv( lapack_int* idist, lapack_int* iseed, lapack_int* n, lapack_complex_float* x ); void LAPACK_zlarnv( lapack_int* idist, lapack_int* iseed, lapack_int* n, lapack_complex_double* x ); void LAPACK_sgeqr2( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int *info ); void LAPACK_dgeqr2( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int *info ); void LAPACK_cgeqr2( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int *info ); void LAPACK_zgeqr2( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int *info ); void LAPACK_slacn2( lapack_int* n, float* v, float* x, lapack_int* isgn, float* est, lapack_int* kase, lapack_int* isave ); void LAPACK_dlacn2( lapack_int* n, double* v, double* x, lapack_int* isgn, double* est, lapack_int* kase, lapack_int* isave ); void LAPACK_clacn2( lapack_int* n, lapack_complex_float* v, lapack_complex_float* x, float* est, lapack_int* kase, lapack_int* isave ); void LAPACK_zlacn2( lapack_int* n, lapack_complex_double* v, lapack_complex_double* x, double* est, lapack_int* kase, lapack_int* isave ); void LAPACK_slacpy( char* uplo, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, float* b, lapack_int* ldb ); void LAPACK_dlacpy( char* uplo, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, double* b, lapack_int* ldb ); void LAPACK_clacpy( char* uplo, lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb ); void LAPACK_zlacpy( char* uplo, lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb ); void LAPACK_clacp2( char* uplo, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb ); void LAPACK_zlacp2( char* uplo, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb ); void LAPACK_sgetf2( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_dgetf2( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_cgetf2( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_zgetf2( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_int *info ); void LAPACK_slaswp( lapack_int* n, float* a, lapack_int* lda, lapack_int* k1, lapack_int* k2, const lapack_int* ipiv, lapack_int* incx ); void LAPACK_dlaswp( lapack_int* n, double* a, lapack_int* lda, lapack_int* k1, lapack_int* k2, const lapack_int* ipiv, lapack_int* incx ); void LAPACK_claswp( lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int* k1, lapack_int* k2, const lapack_int* ipiv, lapack_int* incx ); void LAPACK_zlaswp( lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int* k1, lapack_int* k2, const lapack_int* ipiv, lapack_int* incx ); float LAPACK_slange( char* norm, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, float* work ); double LAPACK_dlange( char* norm, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, double* work ); float LAPACK_clange( char* norm, lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* work ); double LAPACK_zlange( char* norm, lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* work ); float LAPACK_clanhe( char* norm, char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* work ); double LAPACK_zlanhe( char* norm, char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* work ); float LAPACK_slansy( char* norm, char* uplo, lapack_int* n, const float* a, lapack_int* lda, float* work ); double LAPACK_dlansy( char* norm, char* uplo, lapack_int* n, const double* a, lapack_int* lda, double* work ); float LAPACK_clansy( char* norm, char* uplo, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* work ); double LAPACK_zlansy( char* norm, char* uplo, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* work ); float LAPACK_slantr( char* norm, char* uplo, char* diag, lapack_int* m, lapack_int* n, const float* a, lapack_int* lda, float* work ); double LAPACK_dlantr( char* norm, char* uplo, char* diag, lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, double* work ); float LAPACK_clantr( char* norm, char* uplo, char* diag, lapack_int* m, lapack_int* n, const lapack_complex_float* a, lapack_int* lda, float* work ); double LAPACK_zlantr( char* norm, char* uplo, char* diag, lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, double* work ); float LAPACK_slamch( char* cmach ); double LAPACK_dlamch( char* cmach ); void LAPACK_sgelq2( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* tau, float* work, lapack_int *info ); void LAPACK_dgelq2( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* tau, double* work, lapack_int *info ); void LAPACK_cgelq2( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* tau, lapack_complex_float* work, lapack_int *info ); void LAPACK_zgelq2( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* tau, lapack_complex_double* work, lapack_int *info ); void LAPACK_slarfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, const float* v, lapack_int* ldv, const float* t, lapack_int* ldt, float* c, lapack_int* ldc, float* work, lapack_int* ldwork ); void LAPACK_dlarfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, const double* v, lapack_int* ldv, const double* t, lapack_int* ldt, double* c, lapack_int* ldc, double* work, lapack_int* ldwork ); void LAPACK_clarfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_float* v, lapack_int* ldv, const lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int* ldwork ); void LAPACK_zlarfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, const lapack_complex_double* v, lapack_int* ldv, const lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int* ldwork ); void LAPACK_slarfg( lapack_int* n, float* alpha, float* x, lapack_int* incx, float* tau ); void LAPACK_dlarfg( lapack_int* n, double* alpha, double* x, lapack_int* incx, double* tau ); void LAPACK_clarfg( lapack_int* n, lapack_complex_float* alpha, lapack_complex_float* x, lapack_int* incx, lapack_complex_float* tau ); void LAPACK_zlarfg( lapack_int* n, lapack_complex_double* alpha, lapack_complex_double* x, lapack_int* incx, lapack_complex_double* tau ); void LAPACK_slarft( char* direct, char* storev, lapack_int* n, lapack_int* k, const float* v, lapack_int* ldv, const float* tau, float* t, lapack_int* ldt ); void LAPACK_dlarft( char* direct, char* storev, lapack_int* n, lapack_int* k, const double* v, lapack_int* ldv, const double* tau, double* t, lapack_int* ldt ); void LAPACK_clarft( char* direct, char* storev, lapack_int* n, lapack_int* k, const lapack_complex_float* v, lapack_int* ldv, const lapack_complex_float* tau, lapack_complex_float* t, lapack_int* ldt ); void LAPACK_zlarft( char* direct, char* storev, lapack_int* n, lapack_int* k, const lapack_complex_double* v, lapack_int* ldv, const lapack_complex_double* tau, lapack_complex_double* t, lapack_int* ldt ); void LAPACK_slarfx( char* side, lapack_int* m, lapack_int* n, const float* v, float* tau, float* c, lapack_int* ldc, float* work ); void LAPACK_dlarfx( char* side, lapack_int* m, lapack_int* n, const double* v, double* tau, double* c, lapack_int* ldc, double* work ); void LAPACK_clarfx( char* side, lapack_int* m, lapack_int* n, const lapack_complex_float* v, lapack_complex_float* tau, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work ); void LAPACK_zlarfx( char* side, lapack_int* m, lapack_int* n, const lapack_complex_double* v, lapack_complex_double* tau, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work ); void LAPACK_slatms( lapack_int* m, lapack_int* n, char* dist, lapack_int* iseed, char* sym, float* d, lapack_int* mode, float* cond, float* dmax, lapack_int* kl, lapack_int* ku, char* pack, float* a, lapack_int* lda, float* work, lapack_int *info ); void LAPACK_dlatms( lapack_int* m, lapack_int* n, char* dist, lapack_int* iseed, char* sym, double* d, lapack_int* mode, double* cond, double* dmax, lapack_int* kl, lapack_int* ku, char* pack, double* a, lapack_int* lda, double* work, lapack_int *info ); void LAPACK_clatms( lapack_int* m, lapack_int* n, char* dist, lapack_int* iseed, char* sym, float* d, lapack_int* mode, float* cond, float* dmax, lapack_int* kl, lapack_int* ku, char* pack, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* work, lapack_int *info ); void LAPACK_zlatms( lapack_int* m, lapack_int* n, char* dist, lapack_int* iseed, char* sym, double* d, lapack_int* mode, double* cond, double* dmax, lapack_int* kl, lapack_int* ku, char* pack, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* work, lapack_int *info ); void LAPACK_slag2d( lapack_int* m, lapack_int* n, const float* sa, lapack_int* ldsa, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_dlag2s( lapack_int* m, lapack_int* n, const double* a, lapack_int* lda, float* sa, lapack_int* ldsa, lapack_int *info ); void LAPACK_clag2z( lapack_int* m, lapack_int* n, const lapack_complex_float* sa, lapack_int* ldsa, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_zlag2c( lapack_int* m, lapack_int* n, const lapack_complex_double* a, lapack_int* lda, lapack_complex_float* sa, lapack_int* ldsa, lapack_int *info ); void LAPACK_slauum( char* uplo, lapack_int* n, float* a, lapack_int* lda, lapack_int *info ); void LAPACK_dlauum( char* uplo, lapack_int* n, double* a, lapack_int* lda, lapack_int *info ); void LAPACK_clauum( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_int *info ); void LAPACK_zlauum( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_int *info ); void LAPACK_slagge( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const float* d, float* a, lapack_int* lda, lapack_int* iseed, float* work, lapack_int *info ); void LAPACK_dlagge( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const double* d, double* a, lapack_int* lda, lapack_int* iseed, double* work, lapack_int *info ); void LAPACK_clagge( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const float* d, lapack_complex_float* a, lapack_int* lda, lapack_int* iseed, lapack_complex_float* work, lapack_int *info ); void LAPACK_zlagge( lapack_int* m, lapack_int* n, lapack_int* kl, lapack_int* ku, const double* d, lapack_complex_double* a, lapack_int* lda, lapack_int* iseed, lapack_complex_double* work, lapack_int *info ); void LAPACK_slaset( char* uplo, lapack_int* m, lapack_int* n, float* alpha, float* beta, float* a, lapack_int* lda ); void LAPACK_dlaset( char* uplo, lapack_int* m, lapack_int* n, double* alpha, double* beta, double* a, lapack_int* lda ); void LAPACK_claset( char* uplo, lapack_int* m, lapack_int* n, lapack_complex_float* alpha, lapack_complex_float* beta, lapack_complex_float* a, lapack_int* lda ); void LAPACK_zlaset( char* uplo, lapack_int* m, lapack_int* n, lapack_complex_double* alpha, lapack_complex_double* beta, lapack_complex_double* a, lapack_int* lda ); void LAPACK_slasrt( char* id, lapack_int* n, float* d, lapack_int *info ); void LAPACK_dlasrt( char* id, lapack_int* n, double* d, lapack_int *info ); void LAPACK_claghe( lapack_int* n, lapack_int* k, const float* d, lapack_complex_float* a, lapack_int* lda, lapack_int* iseed, lapack_complex_float* work, lapack_int *info ); void LAPACK_zlaghe( lapack_int* n, lapack_int* k, const double* d, lapack_complex_double* a, lapack_int* lda, lapack_int* iseed, lapack_complex_double* work, lapack_int *info ); void LAPACK_slagsy( lapack_int* n, lapack_int* k, const float* d, float* a, lapack_int* lda, lapack_int* iseed, float* work, lapack_int *info ); void LAPACK_dlagsy( lapack_int* n, lapack_int* k, const double* d, double* a, lapack_int* lda, lapack_int* iseed, double* work, lapack_int *info ); void LAPACK_clagsy( lapack_int* n, lapack_int* k, const float* d, lapack_complex_float* a, lapack_int* lda, lapack_int* iseed, lapack_complex_float* work, lapack_int *info ); void LAPACK_zlagsy( lapack_int* n, lapack_int* k, const double* d, lapack_complex_double* a, lapack_int* lda, lapack_int* iseed, lapack_complex_double* work, lapack_int *info ); void LAPACK_slapmr( lapack_logical* forwrd, lapack_int* m, lapack_int* n, float* x, lapack_int* ldx, lapack_int* k ); void LAPACK_dlapmr( lapack_logical* forwrd, lapack_int* m, lapack_int* n, double* x, lapack_int* ldx, lapack_int* k ); void LAPACK_clapmr( lapack_logical* forwrd, lapack_int* m, lapack_int* n, lapack_complex_float* x, lapack_int* ldx, lapack_int* k ); void LAPACK_zlapmr( lapack_logical* forwrd, lapack_int* m, lapack_int* n, lapack_complex_double* x, lapack_int* ldx, lapack_int* k ); float LAPACK_slapy2( float* x, float* y ); double LAPACK_dlapy2( double* x, double* y ); float LAPACK_slapy3( float* x, float* y, float* z ); double LAPACK_dlapy3( double* x, double* y, double* z ); void LAPACK_slartgp( float* f, float* g, float* cs, float* sn, float* r ); void LAPACK_dlartgp( double* f, double* g, double* cs, double* sn, double* r ); void LAPACK_slartgs( float* x, float* y, float* sigma, float* cs, float* sn ); void LAPACK_dlartgs( double* x, double* y, double* sigma, double* cs, double* sn ); // LAPACK 3.3.0 void LAPACK_cbbcsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, lapack_int* m, lapack_int* p, lapack_int* q, float* theta, float* phi, lapack_complex_float* u1, lapack_int* ldu1, lapack_complex_float* u2, lapack_int* ldu2, lapack_complex_float* v1t, lapack_int* ldv1t, lapack_complex_float* v2t, lapack_int* ldv2t, float* b11d, float* b11e, float* b12d, float* b12e, float* b21d, float* b21e, float* b22d, float* b22e, float* rwork, lapack_int* lrwork , lapack_int *info ); void LAPACK_cheswapr( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* i1, lapack_int* i2 ); void LAPACK_chetri2( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int* lwork , lapack_int *info ); void LAPACK_chetri2x( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int* nb , lapack_int *info ); void LAPACK_chetrs2( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work , lapack_int *info ); void LAPACK_csyconv( char* uplo, char* way, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work , lapack_int *info ); void LAPACK_csyswapr( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* i1, lapack_int* i2 ); void LAPACK_csytri2( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int* lwork , lapack_int *info ); void LAPACK_csytri2x( char* uplo, lapack_int* n, lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int* nb , lapack_int *info ); void LAPACK_csytrs2( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work , lapack_int *info ); void LAPACK_cunbdb( char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, lapack_complex_float* x11, lapack_int* ldx11, lapack_complex_float* x12, lapack_int* ldx12, lapack_complex_float* x21, lapack_int* ldx21, lapack_complex_float* x22, lapack_int* ldx22, float* theta, float* phi, lapack_complex_float* taup1, lapack_complex_float* taup2, lapack_complex_float* tauq1, lapack_complex_float* tauq2, lapack_complex_float* work, lapack_int* lwork , lapack_int *info ); void LAPACK_cuncsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, lapack_complex_float* x11, lapack_int* ldx11, lapack_complex_float* x12, lapack_int* ldx12, lapack_complex_float* x21, lapack_int* ldx21, lapack_complex_float* x22, lapack_int* ldx22, float* theta, lapack_complex_float* u1, lapack_int* ldu1, lapack_complex_float* u2, lapack_int* ldu2, lapack_complex_float* v1t, lapack_int* ldv1t, lapack_complex_float* v2t, lapack_int* ldv2t, lapack_complex_float* work, lapack_int* lwork, float* rwork, lapack_int* lrwork, lapack_int* iwork , lapack_int *info ); void LAPACK_dbbcsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, lapack_int* m, lapack_int* p, lapack_int* q, double* theta, double* phi, double* u1, lapack_int* ldu1, double* u2, lapack_int* ldu2, double* v1t, lapack_int* ldv1t, double* v2t, lapack_int* ldv2t, double* b11d, double* b11e, double* b12d, double* b12e, double* b21d, double* b21e, double* b22d, double* b22e, double* work, lapack_int* lwork , lapack_int *info ); void LAPACK_dorbdb( char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, double* x11, lapack_int* ldx11, double* x12, lapack_int* ldx12, double* x21, lapack_int* ldx21, double* x22, lapack_int* ldx22, double* theta, double* phi, double* taup1, double* taup2, double* tauq1, double* tauq2, double* work, lapack_int* lwork , lapack_int *info ); void LAPACK_dorcsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, double* x11, lapack_int* ldx11, double* x12, lapack_int* ldx12, double* x21, lapack_int* ldx21, double* x22, lapack_int* ldx22, double* theta, double* u1, lapack_int* ldu1, double* u2, lapack_int* ldu2, double* v1t, lapack_int* ldv1t, double* v2t, lapack_int* ldv2t, double* work, lapack_int* lwork, lapack_int* iwork , lapack_int *info ); void LAPACK_dsyconv( char* uplo, char* way, lapack_int* n, double* a, lapack_int* lda, const lapack_int* ipiv, double* work , lapack_int *info ); void LAPACK_dsyswapr( char* uplo, lapack_int* n, double* a, lapack_int* i1, lapack_int* i2 ); void LAPACK_dsytri2( char* uplo, lapack_int* n, double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int* lwork , lapack_int *info ); void LAPACK_dsytri2x( char* uplo, lapack_int* n, double* a, lapack_int* lda, const lapack_int* ipiv, double* work, lapack_int* nb , lapack_int *info ); void LAPACK_dsytrs2( char* uplo, lapack_int* n, lapack_int* nrhs, const double* a, lapack_int* lda, const lapack_int* ipiv, double* b, lapack_int* ldb, double* work , lapack_int *info ); void LAPACK_sbbcsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, lapack_int* m, lapack_int* p, lapack_int* q, float* theta, float* phi, float* u1, lapack_int* ldu1, float* u2, lapack_int* ldu2, float* v1t, lapack_int* ldv1t, float* v2t, lapack_int* ldv2t, float* b11d, float* b11e, float* b12d, float* b12e, float* b21d, float* b21e, float* b22d, float* b22e, float* work, lapack_int* lwork , lapack_int *info ); void LAPACK_sorbdb( char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, float* x11, lapack_int* ldx11, float* x12, lapack_int* ldx12, float* x21, lapack_int* ldx21, float* x22, lapack_int* ldx22, float* theta, float* phi, float* taup1, float* taup2, float* tauq1, float* tauq2, float* work, lapack_int* lwork , lapack_int *info ); void LAPACK_sorcsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, float* x11, lapack_int* ldx11, float* x12, lapack_int* ldx12, float* x21, lapack_int* ldx21, float* x22, lapack_int* ldx22, float* theta, float* u1, lapack_int* ldu1, float* u2, lapack_int* ldu2, float* v1t, lapack_int* ldv1t, float* v2t, lapack_int* ldv2t, float* work, lapack_int* lwork, lapack_int* iwork , lapack_int *info ); void LAPACK_ssyconv( char* uplo, char* way, lapack_int* n, float* a, lapack_int* lda, const lapack_int* ipiv, float* work , lapack_int *info ); void LAPACK_ssyswapr( char* uplo, lapack_int* n, float* a, lapack_int* i1, lapack_int* i2 ); void LAPACK_ssytri2( char* uplo, lapack_int* n, float* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_float* work, lapack_int* lwork , lapack_int *info ); void LAPACK_ssytri2x( char* uplo, lapack_int* n, float* a, lapack_int* lda, const lapack_int* ipiv, float* work, lapack_int* nb , lapack_int *info ); void LAPACK_ssytrs2( char* uplo, lapack_int* n, lapack_int* nrhs, const float* a, lapack_int* lda, const lapack_int* ipiv, float* b, lapack_int* ldb, float* work , lapack_int *info ); void LAPACK_zbbcsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, lapack_int* m, lapack_int* p, lapack_int* q, double* theta, double* phi, lapack_complex_double* u1, lapack_int* ldu1, lapack_complex_double* u2, lapack_int* ldu2, lapack_complex_double* v1t, lapack_int* ldv1t, lapack_complex_double* v2t, lapack_int* ldv2t, double* b11d, double* b11e, double* b12d, double* b12e, double* b21d, double* b21e, double* b22d, double* b22e, double* rwork, lapack_int* lrwork , lapack_int *info ); void LAPACK_zheswapr( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* i1, lapack_int* i2 ); void LAPACK_zhetri2( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int* lwork , lapack_int *info ); void LAPACK_zhetri2x( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int* nb , lapack_int *info ); void LAPACK_zhetrs2( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work , lapack_int *info ); void LAPACK_zsyconv( char* uplo, char* way, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work , lapack_int *info ); void LAPACK_zsyswapr( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* i1, lapack_int* i2 ); void LAPACK_zsytri2( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int* lwork , lapack_int *info ); void LAPACK_zsytri2x( char* uplo, lapack_int* n, lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* work, lapack_int* nb , lapack_int *info ); void LAPACK_zsytrs2( char* uplo, lapack_int* n, lapack_int* nrhs, const lapack_complex_double* a, lapack_int* lda, const lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work , lapack_int *info ); void LAPACK_zunbdb( char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, lapack_complex_double* x11, lapack_int* ldx11, lapack_complex_double* x12, lapack_int* ldx12, lapack_complex_double* x21, lapack_int* ldx21, lapack_complex_double* x22, lapack_int* ldx22, double* theta, double* phi, lapack_complex_double* taup1, lapack_complex_double* taup2, lapack_complex_double* tauq1, lapack_complex_double* tauq2, lapack_complex_double* work, lapack_int* lwork , lapack_int *info ); void LAPACK_zuncsd( char* jobu1, char* jobu2, char* jobv1t, char* jobv2t, char* trans, char* signs, lapack_int* m, lapack_int* p, lapack_int* q, lapack_complex_double* x11, lapack_int* ldx11, lapack_complex_double* x12, lapack_int* ldx12, lapack_complex_double* x21, lapack_int* ldx21, lapack_complex_double* x22, lapack_int* ldx22, double* theta, lapack_complex_double* u1, lapack_int* ldu1, lapack_complex_double* u2, lapack_int* ldu2, lapack_complex_double* v1t, lapack_int* ldv1t, lapack_complex_double* v2t, lapack_int* ldv2t, lapack_complex_double* work, lapack_int* lwork, double* rwork, lapack_int* lrwork, lapack_int* iwork , lapack_int *info ); // LAPACK 3.4.0 void LAPACK_sgemqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* nb, const float* v, lapack_int* ldv, const float* t, lapack_int* ldt, float* c, lapack_int* ldc, float* work, lapack_int *info ); void LAPACK_dgemqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* nb, const double* v, lapack_int* ldv, const double* t, lapack_int* ldt, double* c, lapack_int* ldc, double* work, lapack_int *info ); void LAPACK_cgemqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* nb, const lapack_complex_float* v, lapack_int* ldv, const lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* c, lapack_int* ldc, lapack_complex_float* work, lapack_int *info ); void LAPACK_zgemqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* nb, const lapack_complex_double* v, lapack_int* ldv, const lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* c, lapack_int* ldc, lapack_complex_double* work, lapack_int *info ); void LAPACK_sgeqrt( lapack_int* m, lapack_int* n, lapack_int* nb, float* a, lapack_int* lda, float* t, lapack_int* ldt, float* work, lapack_int *info ); void LAPACK_dgeqrt( lapack_int* m, lapack_int* n, lapack_int* nb, double* a, lapack_int* lda, double* t, lapack_int* ldt, double* work, lapack_int *info ); void LAPACK_cgeqrt( lapack_int* m, lapack_int* n, lapack_int* nb, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* work, lapack_int *info ); void LAPACK_zgeqrt( lapack_int* m, lapack_int* n, lapack_int* nb, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* work, lapack_int *info ); void LAPACK_sgeqrt2( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* t, lapack_int* ldt, lapack_int *info ); void LAPACK_dgeqrt2( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* t, lapack_int* ldt, lapack_int *info ); void LAPACK_cgeqrt2( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* t, lapack_int* ldt, lapack_int *info ); void LAPACK_zgeqrt2( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* t, lapack_int* ldt, lapack_int *info ); void LAPACK_sgeqrt3( lapack_int* m, lapack_int* n, float* a, lapack_int* lda, float* t, lapack_int* ldt, lapack_int *info ); void LAPACK_dgeqrt3( lapack_int* m, lapack_int* n, double* a, lapack_int* lda, double* t, lapack_int* ldt, lapack_int *info ); void LAPACK_cgeqrt3( lapack_int* m, lapack_int* n, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* t, lapack_int* ldt, lapack_int *info ); void LAPACK_zgeqrt3( lapack_int* m, lapack_int* n, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* t, lapack_int* ldt, lapack_int *info ); void LAPACK_stpmqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, lapack_int* nb, const float* v, lapack_int* ldv, const float* t, lapack_int* ldt, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* work, lapack_int *info ); void LAPACK_dtpmqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, lapack_int* nb, const double* v, lapack_int* ldv, const double* t, lapack_int* ldt, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* work, lapack_int *info ); void LAPACK_ctpmqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, lapack_int* nb, const lapack_complex_float* v, lapack_int* ldv, const lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work, lapack_int *info ); void LAPACK_ztpmqrt( char* side, char* trans, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, lapack_int* nb, const lapack_complex_double* v, lapack_int* ldv, const lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work, lapack_int *info ); void LAPACK_dtpqrt( lapack_int* m, lapack_int* n, lapack_int* l, lapack_int* nb, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* t, lapack_int* ldt, double* work, lapack_int *info ); void LAPACK_ctpqrt( lapack_int* m, lapack_int* n, lapack_int* l, lapack_int* nb, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* work, lapack_int *info ); void LAPACK_ztpqrt( lapack_int* m, lapack_int* n, lapack_int* l, lapack_int* nb, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* work, lapack_int *info ); void LAPACK_stpqrt2( lapack_int* m, lapack_int* n, lapack_int* l, float* a, lapack_int* lda, float* b, lapack_int* ldb, float* t, lapack_int* ldt, lapack_int *info ); void LAPACK_dtpqrt2( lapack_int* m, lapack_int* n, lapack_int* l, double* a, lapack_int* lda, double* b, lapack_int* ldb, double* t, lapack_int* ldt, lapack_int *info ); void LAPACK_ctpqrt2( lapack_int* m, lapack_int* n, lapack_int* l, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* t, lapack_int* ldt, lapack_int *info ); void LAPACK_ztpqrt2( lapack_int* m, lapack_int* n, lapack_int* l, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* t, lapack_int* ldt, lapack_int *info ); void LAPACK_stprfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const float* v, lapack_int* ldv, const float* t, lapack_int* ldt, float* a, lapack_int* lda, float* b, lapack_int* ldb, const float* work, lapack_int* ldwork ); void LAPACK_dtprfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const double* v, lapack_int* ldv, const double* t, lapack_int* ldt, double* a, lapack_int* lda, double* b, lapack_int* ldb, const double* work, lapack_int* ldwork ); void LAPACK_ctprfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const lapack_complex_float* v, lapack_int* ldv, const lapack_complex_float* t, lapack_int* ldt, lapack_complex_float* a, lapack_int* lda, lapack_complex_float* b, lapack_int* ldb, const float* work, lapack_int* ldwork ); void LAPACK_ztprfb( char* side, char* trans, char* direct, char* storev, lapack_int* m, lapack_int* n, lapack_int* k, lapack_int* l, const lapack_complex_double* v, lapack_int* ldv, const lapack_complex_double* t, lapack_int* ldt, lapack_complex_double* a, lapack_int* lda, lapack_complex_double* b, lapack_int* ldb, const double* work, lapack_int* ldwork ); // LAPACK 3.5.0 void LAPACK_ssysv_rook( char* uplo, lapack_int* n, lapack_int* nrhs, float* a, lapack_int* lda, lapack_int* ipiv, float* b, lapack_int* ldb, float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_dsysv_rook( char* uplo, lapack_int* n, lapack_int* nrhs, double* a, lapack_int* lda, lapack_int* ipiv, double* b, lapack_int* ldb, double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_csysv_rook( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_float* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_float* b, lapack_int* ldb, lapack_complex_float* work, lapack_int* lwork, lapack_int *info ); void LAPACK_zsysv_rook( char* uplo, lapack_int* n, lapack_int* nrhs, lapack_complex_double* a, lapack_int* lda, lapack_int* ipiv, lapack_complex_double* b, lapack_int* ldb, lapack_complex_double* work, lapack_int* lwork, lapack_int *info ); void LAPACK_csyr( char* uplo, lapack_int* n, lapack_complex_float* alpha, const lapack_complex_float* x, lapack_int* incx, lapack_complex_float* a, lapack_int* lda ); void LAPACK_zsyr( char* uplo, lapack_int* n, lapack_complex_double* alpha, const lapack_complex_double* x, lapack_int* incx, lapack_complex_double* a, lapack_int* lda ); void LAPACK_ilaver( const lapack_int* vers_major, const lapack_int* vers_minor, const lapack_int* vers_patch ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _LAPACKE_H_ */ bart-0.5.00/src/lapacke/lapacke_cge_nancheck.c000066400000000000000000000054371353046746100211510ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2010, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** * Contents: Native C interface to LAPACK utility function * Author: Intel Corporation * Created in February, 2010 *****************************************************************************/ #include "lapacke_utils.h" /* Check a matrix for NaN entries. */ lapack_logical LAPACKE_cge_nancheck( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float *a, lapack_int lda ) { lapack_int i, j; if( a == NULL ) return (lapack_logical) 0; if( matrix_order == LAPACK_COL_MAJOR ) { for( j = 0; j < n; j++ ) { for( i = 0; i < MIN( m, lda ); i++ ) { if( LAPACK_CISNAN( a[i+(size_t)j*lda] ) ) return (lapack_logical) 1; } } } else if ( matrix_order == LAPACK_ROW_MAJOR ) { for( i = 0; i < m; i++ ) { for( j = 0; j < MIN( n, lda ); j++ ) { if( LAPACK_CISNAN( a[(size_t)i*lda+j] ) ) return (lapack_logical) 1; } } } return (lapack_logical) 0; } bart-0.5.00/src/lapacke/lapacke_cge_trans.c000066400000000000000000000053631353046746100205240ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2010, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** * Contents: Native C interface to LAPACK utility function * Author: Intel Corporation * Created in February, 2010 *****************************************************************************/ #include "lapacke_utils.h" /* Converts input general matrix from row-major(C) to column-major(Fortran) * layout or vice versa. */ void LAPACKE_cge_trans( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* in, lapack_int ldin, lapack_complex_float* out, lapack_int ldout ) { lapack_int i, j, x, y; if( in == NULL || out == NULL ) return; if( matrix_order == LAPACK_COL_MAJOR ) { x = n; y = m; } else if ( matrix_order == LAPACK_ROW_MAJOR ) { x = m; y = n; } else { /* Unknown input layout */ return; } /* In case of incorrect m, n, ldin or ldout the function does nothing */ for( i = 0; i < MIN( y, ldin ); i++ ) { for( j = 0; j < MIN( x, ldout ); j++ ) { out[ (size_t)i*ldout + j ] = in[ (size_t)j*ldin + i ]; } } } bart-0.5.00/src/lapacke/lapacke_cgesdd.c000066400000000000000000000106011353046746100177770ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2011, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************** * Contents: Native high-level C interface to LAPACK function cgesdd * Author: Intel Corporation * Generated November, 2011 *****************************************************************************/ #include "lapacke_utils.h" lapack_int LAPACKE_cgesdd( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* vt, lapack_int ldvt ) { lapack_int info = 0; lapack_int lwork = -1; /* Additional scalars declarations for work arrays */ size_t lrwork; lapack_int* iwork = NULL; float* rwork = NULL; lapack_complex_float* work = NULL; lapack_complex_float work_query; if( matrix_order != LAPACK_COL_MAJOR && matrix_order != LAPACK_ROW_MAJOR ) { LAPACKE_xerbla( "LAPACKE_cgesdd", -1 ); return -1; } #ifndef LAPACK_DISABLE_NAN_CHECK /* Optionally check input matrices for NaNs */ if( LAPACKE_cge_nancheck( matrix_order, m, n, a, lda ) ) { return -5; } #endif /* Additional scalars initializations for work arrays */ if( LAPACKE_lsame( jobz, 'n' ) ) { lrwork = MAX(1,5*MIN(m,n)); } else { lrwork = (size_t)5*MAX(1,MIN(m,n))*MAX(1,MIN(m,n))+7*MIN(m,n); } /* Allocate memory for working array(s) */ iwork = (lapack_int*) LAPACKE_malloc( sizeof(lapack_int) * MAX(1,8*MIN(m,n)) ); if( iwork == NULL ) { info = LAPACK_WORK_MEMORY_ERROR; goto exit_level_0; } rwork = (float*)LAPACKE_malloc( sizeof(float) * lrwork ); if( rwork == NULL ) { info = LAPACK_WORK_MEMORY_ERROR; goto exit_level_1; } /* Query optimal working array(s) size */ info = LAPACKE_cgesdd_work( matrix_order, jobz, m, n, a, lda, s, u, ldu, vt, ldvt, &work_query, lwork, rwork, iwork ); if( info != 0 ) { goto exit_level_2; } lwork = LAPACK_C2INT( work_query ); /* Allocate memory for work arrays */ work = (lapack_complex_float*) LAPACKE_malloc( sizeof(lapack_complex_float) * lwork ); if( work == NULL ) { info = LAPACK_WORK_MEMORY_ERROR; goto exit_level_2; } /* Call middle-level interface */ info = LAPACKE_cgesdd_work( matrix_order, jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork ); /* Release memory and exit */ LAPACKE_free( work ); exit_level_2: LAPACKE_free( rwork ); exit_level_1: LAPACKE_free( iwork ); exit_level_0: if( info == LAPACK_WORK_MEMORY_ERROR ) { LAPACKE_xerbla( "LAPACKE_cgesdd", info ); } return info; } bart-0.5.00/src/lapacke/lapacke_cgesdd_work.c000066400000000000000000000161611353046746100210500ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2011, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************** * Contents: Native middle-level C interface to LAPACK function cgesdd * Author: Intel Corporation * Generated November, 2011 *****************************************************************************/ #include "lapacke_utils.h" lapack_int LAPACKE_cgesdd_work( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_float* a, lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu, lapack_complex_float* vt, lapack_int ldvt, lapack_complex_float* work, lapack_int lwork, float* rwork, lapack_int* iwork ) { lapack_int info = 0; if( matrix_order == LAPACK_COL_MAJOR ) { /* Call LAPACK function and adjust info */ LAPACK_cgesdd( &jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, rwork, iwork, &info ); if( info < 0 ) { info = info - 1; } } else if( matrix_order == LAPACK_ROW_MAJOR ) { lapack_int nrows_u = ( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && m=n) ) ) { vt_t = (lapack_complex_float*) LAPACKE_malloc( sizeof(lapack_complex_float) * ldvt_t * MAX(1,n) ); if( vt_t == NULL ) { info = LAPACK_TRANSPOSE_MEMORY_ERROR; goto exit_level_2; } } /* Transpose input matrices */ LAPACKE_cge_trans( matrix_order, m, n, a, lda, a_t, lda_t ); /* Call LAPACK function and adjust info */ LAPACK_cgesdd( &jobz, &m, &n, a_t, &lda_t, s, u_t, &ldu_t, vt_t, &ldvt_t, work, &lwork, rwork, iwork, &info ); if( info < 0 ) { info = info - 1; } /* Transpose output matrices */ LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, n, a_t, lda_t, a, lda ); if( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && (m=n) ) ) { LAPACKE_cge_trans( LAPACK_COL_MAJOR, nrows_vt, n, vt_t, ldvt_t, vt, ldvt ); } /* Release memory and exit */ if( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && (m>=n) ) ) { LAPACKE_free( vt_t ); } exit_level_2: if( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && (m (y)) ? (x) : (y)) #endif #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #ifndef MAX3 #define MAX3(x,y,z) (((x) > MAX(y,z)) ? (x) : MAX(y,z)) #endif #ifndef MIN3 #define MIN3(x,y,z) (((x) < MIN(y,z)) ? (x) : MIN(y,z)) #endif #define IS_S_NONZERO(x) ( (x) < 0 || (x) > 0 ) #define IS_D_NONZERO(x) ( (x) < 0 || (x) > 0 ) #define IS_C_NONZERO(x) ( IS_S_NONZERO(*((float*)&x)) || \ IS_S_NONZERO(*(((float*)&x)+1)) ) #define IS_Z_NONZERO(x) ( IS_D_NONZERO(*((double*)&x)) || \ IS_D_NONZERO(*(((double*)&x)+1)) ) /* Error handler */ void LAPACKE_xerbla( const char *name, lapack_int info ); /* Compare two chars (case-insensitive) */ lapack_logical LAPACKE_lsame( char ca, char cb ); /* Functions to convert column-major to row-major 2d arrays and vice versa. */ void LAPACKE_cgb_trans( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_cge_trans( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* in, lapack_int ldin, lapack_complex_float* out, lapack_int ldout ); void LAPACKE_cgg_trans( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float* in, lapack_int ldin, lapack_complex_float* out, lapack_int ldout ); void LAPACKE_chb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_che_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_chp_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *in, lapack_complex_float *out ); void LAPACKE_chs_trans( int matrix_order, lapack_int n, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_cpb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_cpf_trans( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_float *in, lapack_complex_float *out ); void LAPACKE_cpo_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_cpp_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *in, lapack_complex_float *out ); void LAPACKE_csp_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *in, lapack_complex_float *out ); void LAPACKE_csy_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_ctb_trans( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_ctf_trans( int matrix_order, char transr, char uplo, char diag, lapack_int n, const lapack_complex_float *in, lapack_complex_float *out ); void LAPACKE_ctp_trans( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_float *in, lapack_complex_float *out ); void LAPACKE_ctr_trans( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_float *in, lapack_int ldin, lapack_complex_float *out, lapack_int ldout ); void LAPACKE_dgb_trans( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dge_trans( int matrix_order, lapack_int m, lapack_int n, const double* in, lapack_int ldin, double* out, lapack_int ldout ); void LAPACKE_dgg_trans( int matrix_order, lapack_int m, lapack_int n, const double* in, lapack_int ldin, double* out, lapack_int ldout ); void LAPACKE_dhs_trans( int matrix_order, lapack_int n, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dpb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dpf_trans( int matrix_order, char transr, char uplo, lapack_int n, const double *in, double *out ); void LAPACKE_dpo_trans( int matrix_order, char uplo, lapack_int n, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dpp_trans( int matrix_order, char uplo, lapack_int n, const double *in, double *out ); void LAPACKE_dsb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dsp_trans( int matrix_order, char uplo, lapack_int n, const double *in, double *out ); void LAPACKE_dsy_trans( int matrix_order, char uplo, lapack_int n, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dtb_trans( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_dtf_trans( int matrix_order, char transr, char uplo, char diag, lapack_int n, const double *in, double *out ); void LAPACKE_dtp_trans( int matrix_order, char uplo, char diag, lapack_int n, const double *in, double *out ); void LAPACKE_dtr_trans( int matrix_order, char uplo, char diag, lapack_int n, const double *in, lapack_int ldin, double *out, lapack_int ldout ); void LAPACKE_sgb_trans( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_sge_trans( int matrix_order, lapack_int m, lapack_int n, const float* in, lapack_int ldin, float* out, lapack_int ldout ); void LAPACKE_sgg_trans( int matrix_order, lapack_int m, lapack_int n, const float* in, lapack_int ldin, float* out, lapack_int ldout ); void LAPACKE_shs_trans( int matrix_order, lapack_int n, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_spb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_spf_trans( int matrix_order, char transr, char uplo, lapack_int n, const float *in, float *out ); void LAPACKE_spo_trans( int matrix_order, char uplo, lapack_int n, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_spp_trans( int matrix_order, char uplo, lapack_int n, const float *in, float *out ); void LAPACKE_ssb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_ssp_trans( int matrix_order, char uplo, lapack_int n, const float *in, float *out ); void LAPACKE_ssy_trans( int matrix_order, char uplo, lapack_int n, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_stb_trans( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_stf_trans( int matrix_order, char transr, char uplo, char diag, lapack_int n, const float *in, float *out ); void LAPACKE_stp_trans( int matrix_order, char uplo, char diag, lapack_int n, const float *in, float *out ); void LAPACKE_str_trans( int matrix_order, char uplo, char diag, lapack_int n, const float *in, lapack_int ldin, float *out, lapack_int ldout ); void LAPACKE_zgb_trans( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_zge_trans( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* in, lapack_int ldin, lapack_complex_double* out, lapack_int ldout ); void LAPACKE_zgg_trans( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* in, lapack_int ldin, lapack_complex_double* out, lapack_int ldout ); void LAPACKE_zhb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_zhe_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_zhp_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *in, lapack_complex_double *out ); void LAPACKE_zhs_trans( int matrix_order, lapack_int n, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_zpb_trans( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_zpf_trans( int matrix_order, char transr, char uplo, lapack_int n, const lapack_complex_double *in, lapack_complex_double *out ); void LAPACKE_zpo_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_zpp_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *in, lapack_complex_double *out ); void LAPACKE_zsp_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *in, lapack_complex_double *out ); void LAPACKE_zsy_trans( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_ztb_trans( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); void LAPACKE_ztf_trans( int matrix_order, char transr, char uplo, char diag, lapack_int n, const lapack_complex_double *in, lapack_complex_double *out ); void LAPACKE_ztp_trans( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_double *in, lapack_complex_double *out ); void LAPACKE_ztr_trans( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_double *in, lapack_int ldin, lapack_complex_double *out, lapack_int ldout ); /* NaN checkers */ #define LAPACK_SISNAN( x ) ( x != x ) #define LAPACK_DISNAN( x ) ( x != x ) #define LAPACK_CISNAN( x ) ( LAPACK_SISNAN(*((float*) &x)) || \ LAPACK_SISNAN(*(((float*) &x)+1)) ) #define LAPACK_ZISNAN( x ) ( LAPACK_DISNAN(*((double*)&x)) || \ LAPACK_DISNAN(*(((double*)&x)+1)) ) /* NaN checkers for vectors */ lapack_logical LAPACKE_c_nancheck( lapack_int n, const lapack_complex_float *x, lapack_int incx ); lapack_logical LAPACKE_d_nancheck( lapack_int n, const double *x, lapack_int incx ); lapack_logical LAPACKE_s_nancheck( lapack_int n, const float *x, lapack_int incx ); lapack_logical LAPACKE_z_nancheck( lapack_int n, const lapack_complex_double *x, lapack_int incx ); /* NaN checkers for matrices */ lapack_logical LAPACKE_cgb_nancheck( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_float *ab, lapack_int ldab ); lapack_logical LAPACKE_cge_nancheck( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_cgg_nancheck( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_cgt_nancheck( lapack_int n, const lapack_complex_float *dl, const lapack_complex_float *d, const lapack_complex_float *du ); lapack_logical LAPACKE_chb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab ); lapack_logical LAPACKE_che_nancheck( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_chp_nancheck( lapack_int n, const lapack_complex_float *ap ); lapack_logical LAPACKE_chs_nancheck( int matrix_order, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_cpb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab ); lapack_logical LAPACKE_cpf_nancheck( lapack_int n, const lapack_complex_float *a ); lapack_logical LAPACKE_cpo_nancheck( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_cpp_nancheck( lapack_int n, const lapack_complex_float *ap ); lapack_logical LAPACKE_cpt_nancheck( lapack_int n, const float *d, const lapack_complex_float *e ); lapack_logical LAPACKE_csp_nancheck( lapack_int n, const lapack_complex_float *ap ); lapack_logical LAPACKE_cst_nancheck( lapack_int n, const lapack_complex_float *d, const lapack_complex_float *e ); lapack_logical LAPACKE_csy_nancheck( int matrix_order, char uplo, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_ctb_nancheck( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_float* ab, lapack_int ldab ); lapack_logical LAPACKE_ctf_nancheck( int matrix_order, char transr, char uplo, char diag, lapack_int n, const lapack_complex_float *a ); lapack_logical LAPACKE_ctp_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_float *ap ); lapack_logical LAPACKE_ctr_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_float *a, lapack_int lda ); lapack_logical LAPACKE_dgb_nancheck( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const double *ab, lapack_int ldab ); lapack_logical LAPACKE_dge_nancheck( int matrix_order, lapack_int m, lapack_int n, const double *a, lapack_int lda ); lapack_logical LAPACKE_dgg_nancheck( int matrix_order, lapack_int m, lapack_int n, const double *a, lapack_int lda ); lapack_logical LAPACKE_dgt_nancheck( lapack_int n, const double *dl, const double *d, const double *du ); lapack_logical LAPACKE_dhs_nancheck( int matrix_order, lapack_int n, const double *a, lapack_int lda ); lapack_logical LAPACKE_dpb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab ); lapack_logical LAPACKE_dpf_nancheck( lapack_int n, const double *a ); lapack_logical LAPACKE_dpo_nancheck( int matrix_order, char uplo, lapack_int n, const double *a, lapack_int lda ); lapack_logical LAPACKE_dpp_nancheck( lapack_int n, const double *ap ); lapack_logical LAPACKE_dpt_nancheck( lapack_int n, const double *d, const double *e ); lapack_logical LAPACKE_dsb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab ); lapack_logical LAPACKE_dsp_nancheck( lapack_int n, const double *ap ); lapack_logical LAPACKE_dst_nancheck( lapack_int n, const double *d, const double *e ); lapack_logical LAPACKE_dsy_nancheck( int matrix_order, char uplo, lapack_int n, const double *a, lapack_int lda ); lapack_logical LAPACKE_dtb_nancheck( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const double* ab, lapack_int ldab ); lapack_logical LAPACKE_dtf_nancheck( int matrix_order, char transr, char uplo, char diag, lapack_int n, const double *a ); lapack_logical LAPACKE_dtp_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const double *ap ); lapack_logical LAPACKE_dtr_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const double *a, lapack_int lda ); lapack_logical LAPACKE_sgb_nancheck( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const float *ab, lapack_int ldab ); lapack_logical LAPACKE_sge_nancheck( int matrix_order, lapack_int m, lapack_int n, const float *a, lapack_int lda ); lapack_logical LAPACKE_sgg_nancheck( int matrix_order, lapack_int m, lapack_int n, const float *a, lapack_int lda ); lapack_logical LAPACKE_sgt_nancheck( lapack_int n, const float *dl, const float *d, const float *du ); lapack_logical LAPACKE_shs_nancheck( int matrix_order, lapack_int n, const float *a, lapack_int lda ); lapack_logical LAPACKE_spb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab ); lapack_logical LAPACKE_spf_nancheck( lapack_int n, const float *a ); lapack_logical LAPACKE_spo_nancheck( int matrix_order, char uplo, lapack_int n, const float *a, lapack_int lda ); lapack_logical LAPACKE_spp_nancheck( lapack_int n, const float *ap ); lapack_logical LAPACKE_spt_nancheck( lapack_int n, const float *d, const float *e ); lapack_logical LAPACKE_ssb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab ); lapack_logical LAPACKE_ssp_nancheck( lapack_int n, const float *ap ); lapack_logical LAPACKE_sst_nancheck( lapack_int n, const float *d, const float *e ); lapack_logical LAPACKE_ssy_nancheck( int matrix_order, char uplo, lapack_int n, const float *a, lapack_int lda ); lapack_logical LAPACKE_stb_nancheck( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const float* ab, lapack_int ldab ); lapack_logical LAPACKE_stf_nancheck( int matrix_order, char transr, char uplo, char diag, lapack_int n, const float *a ); lapack_logical LAPACKE_stp_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const float *ap ); lapack_logical LAPACKE_str_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const float *a, lapack_int lda ); lapack_logical LAPACKE_zgb_nancheck( int matrix_order, lapack_int m, lapack_int n, lapack_int kl, lapack_int ku, const lapack_complex_double *ab, lapack_int ldab ); lapack_logical LAPACKE_zge_nancheck( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double *a, lapack_int lda ); lapack_logical LAPACKE_zgg_nancheck( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double *a, lapack_int lda ); lapack_logical LAPACKE_zgt_nancheck( lapack_int n, const lapack_complex_double *dl, const lapack_complex_double *d, const lapack_complex_double *du ); lapack_logical LAPACKE_zhb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab ); lapack_logical LAPACKE_zhe_nancheck( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *a, lapack_int lda ); lapack_logical LAPACKE_zhp_nancheck( lapack_int n, const lapack_complex_double *ap ); lapack_logical LAPACKE_zhs_nancheck( int matrix_order, lapack_int n, const lapack_complex_double *a, lapack_int lda ); lapack_logical LAPACKE_zpb_nancheck( int matrix_order, char uplo, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab ); lapack_logical LAPACKE_zpf_nancheck( lapack_int n, const lapack_complex_double *a ); lapack_logical LAPACKE_zpo_nancheck( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *a, lapack_int lda ); lapack_logical LAPACKE_zpp_nancheck( lapack_int n, const lapack_complex_double *ap ); lapack_logical LAPACKE_zpt_nancheck( lapack_int n, const double *d, const lapack_complex_double *e ); lapack_logical LAPACKE_zsp_nancheck( lapack_int n, const lapack_complex_double *ap ); lapack_logical LAPACKE_zst_nancheck( lapack_int n, const lapack_complex_double *d, const lapack_complex_double *e ); lapack_logical LAPACKE_zsy_nancheck( int matrix_order, char uplo, lapack_int n, const lapack_complex_double *a, lapack_int lda ); lapack_logical LAPACKE_ztb_nancheck( int matrix_order, char uplo, char diag, lapack_int n, lapack_int kd, const lapack_complex_double* ab, lapack_int ldab ); lapack_logical LAPACKE_ztf_nancheck( int matrix_order, char transr, char uplo, char diag, lapack_int n, const lapack_complex_double *a ); lapack_logical LAPACKE_ztp_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_double *ap ); lapack_logical LAPACKE_ztr_nancheck( int matrix_order, char uplo, char diag, lapack_int n, const lapack_complex_double *a, lapack_int lda ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _LAPACKE_UTILS_H_ */ bart-0.5.00/src/lapacke/lapacke_xerbla.c000066400000000000000000000044511353046746100200310ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2010, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** * Contents: Native C interface to LAPACK lsame * Author: Intel Corporation * Created in January, 2010 *****************************************************************************/ #include #include "lapacke_utils.h" void LAPACKE_xerbla( const char *name, lapack_int info ) { if( info == LAPACK_WORK_MEMORY_ERROR ) { printf( "Not enough memory to allocate work array in %s\n", name ); } else if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { printf( "Not enough memory to transpose matrix in %s\n", name ); } else if( info < 0 ) { printf( "Wrong parameter %d in %s\n", -(int) info, name ); } } bart-0.5.00/src/lapacke/lapacke_zge_nancheck.c000066400000000000000000000054401353046746100211720ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2010, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** * Contents: Native C interface to LAPACK utility function * Author: Intel Corporation * Created in February, 2010 *****************************************************************************/ #include "lapacke_utils.h" /* Check a matrix for NaN entries. */ lapack_logical LAPACKE_zge_nancheck( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double *a, lapack_int lda ) { lapack_int i, j; if( a == NULL ) return (lapack_logical) 0; if( matrix_order == LAPACK_COL_MAJOR ) { for( j = 0; j < n; j++ ) { for( i = 0; i < MIN( m, lda ); i++ ) { if( LAPACK_ZISNAN( a[i+(size_t)j*lda] ) ) return (lapack_logical) 1; } } } else if ( matrix_order == LAPACK_ROW_MAJOR ) { for( i = 0; i < m; i++ ) { for( j = 0; j < MIN( n, lda ); j++ ) { if( LAPACK_ZISNAN( a[(size_t)i*lda+j] ) ) return (lapack_logical) 1; } } } return (lapack_logical) 0; } bart-0.5.00/src/lapacke/lapacke_zge_trans.c000066400000000000000000000053651353046746100205550ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2010, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************** * Contents: Native C interface to LAPACK utility function * Author: Intel Corporation * Created in February, 2010 *****************************************************************************/ #include "lapacke_utils.h" /* Converts input general matrix from row-major(C) to column-major(Fortran) * layout or vice versa. */ void LAPACKE_zge_trans( int matrix_order, lapack_int m, lapack_int n, const lapack_complex_double* in, lapack_int ldin, lapack_complex_double* out, lapack_int ldout ) { lapack_int i, j, x, y; if( in == NULL || out == NULL ) return; if( matrix_order == LAPACK_COL_MAJOR ) { x = n; y = m; } else if ( matrix_order == LAPACK_ROW_MAJOR ) { x = m; y = n; } else { /* Unknown input layout */ return; } /* In case of incorrect m, n, ldin or ldout the function does nothing */ for( i = 0; i < MIN( y, ldin ); i++ ) { for( j = 0; j < MIN( x, ldout ); j++ ) { out[ (size_t)i*ldout + j ] = in[ (size_t)j*ldin + i ]; } } } bart-0.5.00/src/lapacke/lapacke_zgesdd.c000066400000000000000000000106141353046746100200320ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2011, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************** * Contents: Native high-level C interface to LAPACK function zgesdd * Author: Intel Corporation * Generated November, 2011 *****************************************************************************/ #include "lapacke_utils.h" lapack_int LAPACKE_zgesdd( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* vt, lapack_int ldvt ) { lapack_int info = 0; lapack_int lwork = -1; /* Additional scalars declarations for work arrays */ size_t lrwork; lapack_int* iwork = NULL; double* rwork = NULL; lapack_complex_double* work = NULL; lapack_complex_double work_query; if( matrix_order != LAPACK_COL_MAJOR && matrix_order != LAPACK_ROW_MAJOR ) { LAPACKE_xerbla( "LAPACKE_zgesdd", -1 ); return -1; } #ifndef LAPACK_DISABLE_NAN_CHECK /* Optionally check input matrices for NaNs */ if( LAPACKE_zge_nancheck( matrix_order, m, n, a, lda ) ) { return -5; } #endif /* Additional scalars initializations for work arrays */ if( LAPACKE_lsame( jobz, 'n' ) ) { lrwork = MAX(1,5*MIN(m,n)); } else { lrwork = (size_t)5*MAX(1,MIN(m,n))*MAX(1,MIN(m,n))+7*MIN(m,n); } /* Allocate memory for working array(s) */ iwork = (lapack_int*) LAPACKE_malloc( sizeof(lapack_int) * MAX(1,8*MIN(m,n)) ); if( iwork == NULL ) { info = LAPACK_WORK_MEMORY_ERROR; goto exit_level_0; } rwork = (double*)LAPACKE_malloc( sizeof(double) * lrwork ); if( rwork == NULL ) { info = LAPACK_WORK_MEMORY_ERROR; goto exit_level_1; } /* Query optimal working array(s) size */ info = LAPACKE_zgesdd_work( matrix_order, jobz, m, n, a, lda, s, u, ldu, vt, ldvt, &work_query, lwork, rwork, iwork ); if( info != 0 ) { goto exit_level_2; } lwork = LAPACK_Z2INT( work_query ); /* Allocate memory for work arrays */ work = (lapack_complex_double*) LAPACKE_malloc( sizeof(lapack_complex_double) * lwork ); if( work == NULL ) { info = LAPACK_WORK_MEMORY_ERROR; goto exit_level_2; } /* Call middle-level interface */ info = LAPACKE_zgesdd_work( matrix_order, jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork ); /* Release memory and exit */ LAPACKE_free( work ); exit_level_2: LAPACKE_free( rwork ); exit_level_1: LAPACKE_free( iwork ); exit_level_0: if( info == LAPACK_WORK_MEMORY_ERROR ) { LAPACKE_xerbla( "LAPACKE_zgesdd", info ); } return info; } bart-0.5.00/src/lapacke/lapacke_zgesdd_work.c000066400000000000000000000162001353046746100210710ustar00rootroot00000000000000/***************************************************************************** Copyright (c) 2011, Intel Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************** * Contents: Native middle-level C interface to LAPACK function zgesdd * Author: Intel Corporation * Generated November, 2011 *****************************************************************************/ #include "lapacke_utils.h" lapack_int LAPACKE_zgesdd_work( int matrix_order, char jobz, lapack_int m, lapack_int n, lapack_complex_double* a, lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu, lapack_complex_double* vt, lapack_int ldvt, lapack_complex_double* work, lapack_int lwork, double* rwork, lapack_int* iwork ) { lapack_int info = 0; if( matrix_order == LAPACK_COL_MAJOR ) { /* Call LAPACK function and adjust info */ LAPACK_zgesdd( &jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, rwork, iwork, &info ); if( info < 0 ) { info = info - 1; } } else if( matrix_order == LAPACK_ROW_MAJOR ) { lapack_int nrows_u = ( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && m=n) ) ) { vt_t = (lapack_complex_double*) LAPACKE_malloc( sizeof(lapack_complex_double) * ldvt_t * MAX(1,n) ); if( vt_t == NULL ) { info = LAPACK_TRANSPOSE_MEMORY_ERROR; goto exit_level_2; } } /* Transpose input matrices */ LAPACKE_zge_trans( matrix_order, m, n, a, lda, a_t, lda_t ); /* Call LAPACK function and adjust info */ LAPACK_zgesdd( &jobz, &m, &n, a_t, &lda_t, s, u_t, &ldu_t, vt_t, &ldvt_t, work, &lwork, rwork, iwork, &info ); if( info < 0 ) { info = info - 1; } /* Transpose output matrices */ LAPACKE_zge_trans( LAPACK_COL_MAJOR, m, n, a_t, lda_t, a, lda ); if( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && (m=n) ) ) { LAPACKE_zge_trans( LAPACK_COL_MAJOR, nrows_vt, n, vt_t, ldvt_t, vt, ldvt ); } /* Release memory and exit */ if( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && (m>=n) ) ) { LAPACKE_free( vt_t ); } exit_level_2: if( LAPACKE_lsame( jobz, 'a' ) || LAPACKE_lsame( jobz, 's' ) || ( LAPACKE_lsame( jobz, 'o' ) && (m */ #include #include "misc/misc.h" #include "num/flpmath.h" #include "num/multind.h" #include "linops/linop.h" #include "decompose_complex.h" #ifdef _OPENMP #include #endif struct decompose_complex_s { INTERFACE(linop_data_t); unsigned int N; unsigned int D; unsigned int K; const long* idims; const long* odims; complex float* buffer; }; static DEF_TYPEID(decompose_complex_s); static void decompose_complex_fwd(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(decompose_complex_s, _data); #pragma omp parallel for for (long k = 0; k < data->K; k ++) dst[k] = creal(src[k]) + 1.0i * cimag(src[k + data->K]); } static void decompose_complex_adj(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(decompose_complex_s, _data); md_zreal(data->N, data->odims, dst, src); md_zimag(data->N, data->odims, dst + data->K, src); } static void decompose_complex_nrm(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(decompose_complex_s, _data); md_copy(data->N, data->idims, dst, src, sizeof(complex float)); // Identity. } static void decompose_complex_free(const linop_data_t* _data) { const auto data = CAST_DOWN(decompose_complex_s, _data); xfree(data->idims); xfree(data->odims); xfree(data); } struct linop_s* linop_decompose_complex_create(unsigned int N, unsigned int D, const long dims[N]) { assert(D < N); for (long k = D; k < N; k++) assert(1 == dims[k]); long K = 1; for (long k = 0; k < D; k++) K = K * dims[k]; PTR_ALLOC(struct decompose_complex_s, data); SET_TYPEID(decompose_complex_s, data); long idims[N]; md_copy_dims(N, idims, dims); idims[D] = 2; long odims[N]; md_copy_dims(N, odims, dims); PTR_ALLOC(long[N], idims_alloc); PTR_ALLOC(long[N], odims_alloc); md_copy_dims(N, *idims_alloc, idims); md_copy_dims(N, *odims_alloc, odims); data->N = N; data->D = D; data->K = K; data->idims = *PTR_PASS(idims_alloc); data->odims = *PTR_PASS(odims_alloc); return linop_create(N, odims, N, idims, CAST_UP(PTR_PASS(data)), decompose_complex_fwd, decompose_complex_adj, decompose_complex_nrm, NULL, decompose_complex_free); } bart-0.5.00/src/linops/decompose_complex.h000066400000000000000000000006321353046746100205070ustar00rootroot00000000000000/* Copyright 2019. Massachusetts Institute of Technology. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2019 Siddharth Iyer */ #include "misc/cppwrap.h" extern struct linop_s* linop_decompose_complex_create(unsigned int N, unsigned int D, const long dims[__VLA(N)]); #include "misc/cppwrap.h" bart-0.5.00/src/linops/finite_diff.c000066400000000000000000000463541353046746100172560ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2014. Joseph Y Cheng. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Jonathan Tamir * 2014 Joseph Y Cheng * 2016 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops.h" #include "linops/linop.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/types.h" #include "finite_diff.h" /** * Contains parameters for finite difference * * @param D number of dimensions * @param dims dimensions of input to be differenced * @param str strides of input * @param tmp temporary storage for computing finite difference * @param tmp2 temporary storage for computing cumulative sum * @param flags bitmask for applying operators * @param order finite difference order (currently only 1) * @param snip TRUE to zero out first dimension */ struct fdiff_s { INTERFACE(linop_data_t); unsigned int D; long* dims; long* str; unsigned int flags; int order; bool snip; }; static DEF_TYPEID(fdiff_s); /* * Implements finite difference operator (order 1 for now) * using circular shift: diff(x) = x - circshift(x) * @param snip Keeps first entry if snip = false; clear first entry if snip = true * * optr = [iptr(1); diff(iptr)] */ static void md_zfinitediff_core2(unsigned int D, const long dims[D], unsigned int flags, bool snip, complex float* tmp, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { md_copy2(D, dims, istrs, tmp, istrs, iptr, sizeof(complex float)); long zdims[D]; long center[D]; md_select_dims(D, ~0, zdims, dims); memset(center, 0, D * sizeof(long)); for (unsigned int i=0; i < D; i++) { if (MD_IS_SET(flags, i)) { center[i] = 1; // order md_circ_shift2(D, dims, center, ostrs, optr, istrs, tmp, sizeof(complex float)); zdims[i] = 1; if (!snip) // zero out first dimension before subtracting md_clear2(D, zdims, ostrs, optr, sizeof(complex float)); md_zsub2(D, dims, ostrs, optr, istrs, tmp, ostrs, optr); md_copy2(D, dims, ostrs, tmp, ostrs, optr, sizeof(complex float)); if (snip) // zero out first dimension after subtracting md_clear2(D, zdims, ostrs, optr, sizeof(complex float)); center[i] = 0; zdims[i] = dims[i]; } } } /* * Finite difference along dimensions specified by flags (without strides) * Keeps first entry so that dimensions are unchanged * * optr = [iptr(1); diff(iptr)] */ void md_zfinitediff(unsigned int D, const long dims[D], unsigned int flags, bool snip, complex float* optr, const complex float* iptr) { long str[D]; md_calc_strides(D, str, dims, sizeof(complex float)); md_zfinitediff2(D, dims, flags, snip, str, optr, str, iptr); } /* * Finite difference along dimensions specified by flags (with strides) * Keeps first entry so that dimensions are unchanged * * optr = [iptr(1); diff(iptr)] */ void md_zfinitediff2(unsigned int D, const long dims[D], unsigned int flags, bool snip, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { complex float* tmp = md_alloc_sameplace(D, dims, sizeof(complex float), optr); md_zfinitediff_core2(D, dims, flags, snip, tmp, ostrs, optr, istrs, iptr); md_free(tmp); } /* * Implements cumulative sum operator (order 1 for now) * using circular shift: cumsum(x) = x + circshift(x,1) + circshift(x,2) + ... * * optr = cumsum(iptr) */ static void md_zcumsum_core2(unsigned int D, const long dims[D], unsigned int flags, complex float* tmp, complex float* tmp2, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { //out = dx md_copy2(D, dims, ostrs, optr, istrs, iptr, sizeof(complex float)); md_copy2(D, dims, istrs, tmp, istrs, iptr, sizeof(complex float)); long zdims[D]; long center[D]; md_select_dims(D, ~0, zdims, dims); memset(center, 0, D * sizeof(long)); for (unsigned int i=0; i < D; i++) { if (MD_IS_SET(flags, i)) { for (int d=1; d < dims[i]; d++) { // tmp = circshift(tmp, i) center[i] = d; md_circ_shift2(D, dims, center, istrs, tmp2, istrs, tmp, sizeof(complex float)); zdims[i] = d; // tmp(1:d,:) = 0 md_clear2(D, zdims, istrs, tmp2, sizeof(complex float)); //md_zsmul2(D, zdims, istrs, tmp2, istrs, tmp2, 0.); //dump_cfl("tmp2", D, dims, tmp2); // out = out + tmp md_zadd2(D, dims, ostrs, optr, istrs, tmp2, ostrs, optr); //md_copy2(D, dims, ostrs, tmp, ostrs, optr, sizeof(complex float)); } md_copy2(D, dims, ostrs, tmp, ostrs, optr, sizeof(complex float)); center[i] = 0; zdims[i] = dims[i]; } } } /* * Cumulative sum along dimensions specified by flags (without strides) * * optr = cumsum(iptr) */ void md_zcumsum(unsigned int D, const long dims[D], unsigned int flags, complex float* optr, const complex float* iptr) { long str[D]; md_calc_strides(D, str, dims, sizeof(complex float)); md_zcumsum2(D, dims, flags, str, optr, str, iptr); } /* * Cumulative sum along dimensions specified by flags (with strides) * * optr = cumsum(iptr) */ void md_zcumsum2(unsigned int D, const long dims[D], unsigned int flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { complex float* tmp = md_alloc_sameplace(D, dims, CFL_SIZE, optr); complex float* tmp2 = md_alloc_sameplace(D, dims, CFL_SIZE, optr); md_zcumsum_core2(D, dims, flags, tmp, tmp2, ostrs, optr, istrs, iptr); md_free(tmp); md_free(tmp2); } /* * Finite difference operator along specified dimensions. * Keeps the original value for the first entry * * optr = [iptr(1); diff(iptr)] */ static void fdiff_apply(const linop_data_t* _data, complex float* optr, const complex float* iptr) { const auto data = CAST_DOWN(fdiff_s, _data); complex float* tmp = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr); md_zfinitediff_core2(data->D, data->dims, data->flags, data->snip, tmp, data->str, optr, data->str, iptr); md_free(tmp); } /* * Adjoint of finite difference operator along specified dimensions. * Equivalent to finite difference in reverse order * * @param snip if false: keeps the original value for the last entry; * if true: implements the adjoint of the difference matrix with all zero first row * * optr = [-diff(iptr); iptr(end)] = flip(fdiff_apply(flip(iptr))) */ static void fdiff_apply_adjoint(const linop_data_t* _data, complex float* optr, const complex float* iptr) { const auto data = CAST_DOWN(fdiff_s, _data); md_copy2(data->D, data->dims, data->str, optr, data->str, iptr, CFL_SIZE); for (unsigned int i=0; i < data->D; i++) { unsigned int single_flag = data->flags & MD_BIT(i); if (single_flag) { complex float* tmp = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr); complex float* tmp2 = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr); md_flip2(data->D, data->dims, single_flag, data->str, tmp2, data->str, optr, CFL_SIZE); md_zfinitediff_core2(data->D, data->dims, single_flag, false, tmp, data->str, tmp2, data->str, tmp2); md_flip2(data->D, data->dims, single_flag, data->str, optr, data->str, tmp2, CFL_SIZE); md_free(tmp2); md_free(tmp); if (data->snip) { long zdims[data->D]; md_select_dims(data->D, ~0, zdims, data->dims); zdims[i] = 1; md_zsub2(data->D, zdims, data->str, optr, data->str, optr, data->str, iptr); } } } } /* * Cumulative sum - inverse of finite difference operator * * optr = cumsum(iptr); */ static void cumsum_apply(const linop_data_t* _data, float lambda, complex float* optr, const complex float* iptr) { const auto data = CAST_DOWN(fdiff_s, _data); assert(0. == lambda); complex float* tmp = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr); complex float* tmp2 = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr); md_zcumsum_core2(data->D, data->dims, data->flags, tmp, tmp2, data->str, optr, data->str, iptr); md_free(tmp2); md_free(tmp); } static void finite_diff_del(const linop_data_t* _data) { const auto data = CAST_DOWN(fdiff_s, _data); xfree(data->dims); xfree(data->str); xfree(data); } /** * Initialize finite difference operator * * @param D number of dimensions * @param dim input dimensions * @param flags bitmask for applying operator * @param snip true: clear initial entry (i.c.); false: keep initial entry (i.c.) * * Returns a pointer to the finite difference operator */ extern const struct linop_s* linop_finitediff_create(unsigned int D, const long dim[D], const unsigned long flags, bool snip) { PTR_ALLOC(struct fdiff_s, data); SET_TYPEID(fdiff_s, data); data->D = D; data->flags = flags; data->order = 1; data->snip = snip; data->dims = *TYPE_ALLOC(long[D]); md_copy_dims(D, data->dims, dim); data->str = *TYPE_ALLOC(long[D]); md_calc_strides(D, data->str, data->dims, CFL_SIZE); return linop_create(D, dim, D, dim, CAST_UP(PTR_PASS(data)), fdiff_apply, fdiff_apply_adjoint, NULL, cumsum_apply, finite_diff_del); } void fd_proj_noninc(const struct linop_s* o, complex float* optr, const complex float* iptr) { struct fdiff_s* data = (struct fdiff_s*)linop_get_data(o); // FIXME: CAST? dump_cfl("impre", data->D, data->dims, iptr); complex float* tmp2 = md_alloc_sameplace(data->D, data->dims, CFL_SIZE, optr); linop_forward_unchecked(o, tmp2, iptr); long tmpdim = data->dims[0]; long dims2[data->D]; md_select_dims(data->D, ~0u, dims2, data->dims); dims2[0] *= 2; dump_cfl("dxpre", data->D, data->dims, tmp2); md_smin(data->D, dims2, (float*)optr, (float*)tmp2, 0.); // add back initial value dims2[0] = tmpdim; for (unsigned int i = 0; i < data->D; i++) { if (MD_IS_SET(data->flags, i)) { dims2[i] = 1; md_copy2(data->D, dims2, data->str, optr, data->str, tmp2, CFL_SIZE); break; } } dump_cfl("dxpost", data->D, data->dims, optr); linop_norm_inv_unchecked(o, 0., optr, optr); dump_cfl("impost", data->D, data->dims, optr); md_free(tmp2); } /** * Internal data structure used for zfinitediff operator */ struct zfinitediff_data { INTERFACE(linop_data_t); unsigned int D; long dim_diff; bool do_circdiff; long* dims_in; long* strides_in; long* dims_adj; long* strides_adj; size_t size; }; static DEF_TYPEID(zfinitediff_data); /** * Originally used md_circshift, but couldn't get it right, so I just * wrote it out for now (also avoids extra memory) */ static void zfinitediff_apply(const linop_data_t* _data, complex float* optr, const complex float* iptr) { // if (docircshift) // out(..,1:(end-1),..) = in(..,1:(end-1),..) - in(..,2:end,..) // out(..,end,..) = in(..,end,..) - in(..,1,..) // else // out = in(..,1:(end-1),..) - in(..,2:end,..) const auto data = CAST_DOWN(zfinitediff_data, _data); unsigned long d = data->dim_diff; long nx = data->dims_in[d]; long dims_sub[data->D]; md_copy_dims(data->D, dims_sub, data->dims_in); long off_in, off_adj; if (data->do_circdiff) { // out(..,1:(end-1),..) = in(..,1:(end-1),..) - in(..,2:end,..) dims_sub[d] = nx - 1; off_in = data->strides_in[d] / CFL_SIZE; //off_adj = data->strides_in[d]/CFL_SIZE; md_zsub2(data->D, dims_sub, data->strides_adj, optr, data->strides_in, iptr, data->strides_in, iptr + off_in); // out(..,end,..) = in(..,end,..) - in(..,1,..) dims_sub[d] = 1; off_in = (nx - 1) * data->strides_in[d] / CFL_SIZE; off_adj = (nx - 1) * data->strides_adj[d] / CFL_SIZE; md_zsub2(data->D, dims_sub, data->strides_adj, optr + off_adj, data->strides_in, iptr + off_in, data->strides_in, iptr); } else { // out(..,1:(end-1),..) = in(..,1:(end-1),..) - in(..,2:end,..) dims_sub[d] = nx - 1; off_in = data->strides_in[d] / CFL_SIZE; md_zsub2(data->D, dims_sub, data->strides_adj, optr, data->strides_in, iptr, data->strides_in, iptr + off_in); } /* long i_shift, i_adj, x_orig, x_new; unsigned int d = data->dim_diff; for (unsigned int i = 0; i < md_calc_size(data->D, data->dims_in); i++) { i_shift = i; i_adj = i; x_orig = (i/data->strs_in[d]) % data->dims_in[d]; x_new = x_orig + 1; // shift by 1 while (x_new >= data->dims_in[d]) x_new -= data->dims_in[d]; i_shift += (x_new - x_orig)*data->strs_in[d]; optr[i_adj] = iptr[i] - iptr[i_shift]; */ } static void zfinitediff_adjoint(const linop_data_t* _data, complex float* optr, const complex float* iptr) { const auto data = CAST_DOWN(zfinitediff_data, _data); // if (docircshift) // out(..,2:end,..) = in(..,2:end,..) - in(..,1:(end-1),..) // out(..,1,..) = in(..,1,..) - in(..,end,..) // else // out(..,1,..) = in(..,1,..) // out(..,2:(end-1),..) = in(..,2:end,..) - in(..,1:(end-1),..) // out(..,end,..) = -in(..,end,..); unsigned int d = data->dim_diff; long nx = data->dims_adj[d]; long off_in, off_adj; long dims_sub[data->D]; md_copy_dims(data->D, dims_sub, data->dims_adj); if (data->do_circdiff) { // out(..,2:end,..) = in(..,2:end,..) - in(..,1:(end-1),..) dims_sub[d] = nx - 1; off_adj = data->strides_adj[d] / CFL_SIZE; off_in = data->strides_in[d] / CFL_SIZE; md_zsub2(data->D, dims_sub, data->strides_in, optr + off_in, data->strides_in, iptr + off_adj, data->strides_adj, iptr); // out(..,1,..) = in(..,1,..) - in(..,end,..) dims_sub[d] = 1; off_adj = (nx - 1) * data->strides_adj[d] / CFL_SIZE; off_in = (nx - 1) * data->strides_in[d] / CFL_SIZE; md_zsub2(data->D, dims_sub, data->strides_in, optr, data->strides_adj, iptr, data->strides_adj, iptr + off_adj); } else { // out(..,end,..) = 0 //md_clear2(data->D, data->dims_in, data->strides_in, optr, CFL_SIZE); dims_sub[d] = 1; off_in = nx * data->strides_in[d] / CFL_SIZE; md_clear2(data->D, dims_sub, data->strides_in, optr + off_in, CFL_SIZE); // out(..,1:end-1,:) = in_adj(..,1:end,:) md_copy2(data->D, data->dims_adj, data->strides_in, optr, data->strides_adj, iptr, CFL_SIZE); // out(..,2:end,:) -= in_adj(..,1:end,:) off_in = data->strides_in[d] / CFL_SIZE; md_zsub2(data->D, data->dims_adj, data->strides_in, optr + off_in, data->strides_in, optr + off_in, data->strides_adj, iptr); /* // out(..,1,..) = in_adj(..,1,..) dims_sub[d] = 1; md_copy2(data->D, dims_sub, data->strides_in, optr, data->strides_adj, iptr, CFL_SIZE); // out(..,2:(end-1),..) = in(..,2:end,..) - in(..,1:(end-1),..) dims_sub[d] = nx - 1; off_adj = data->strides_adj[d]/CFL_SIZE; off_in = data->strides_in[d]/CFL_SIZE; md_zsub2(data->D, dims_sub, data->strides_in, optr+off_in, data->strides_adj, iptr+off_adj, data->strides_adj, iptr); // out(..,end,..) = -in(..,end,..); dims_sub[d] = 1; off_adj = (nx - 1) * data->strides_adj[d]/CFL_SIZE; off_in = nx * data->strides_in[d]/CFL_SIZE; // !!!This one operation is really really slow!!! md_zsmul2(data->D, dims_sub, data->strides_in, optr+off_in, data->strides_adj, iptr+off_adj, -1.); */ } } // y = 2*x - circshift(x,center_adj) - circshift(x,center) static void zfinitediff_normal(const linop_data_t* _data, complex float* optr, const complex float* iptr) { const auto data = CAST_DOWN(zfinitediff_data, _data); // Turns out that this is faster, but this requires extra memory. complex float* tmp = md_alloc_sameplace(data->D, data->dims_in, CFL_SIZE, iptr); zfinitediff_apply(_data, tmp, iptr); zfinitediff_adjoint(_data, optr, tmp); md_free(tmp); return; // FIXME: WTF? unsigned long d = data->dim_diff; long nx = data->dims_in[d]; long offset; long dims_sub[data->D]; md_copy_dims(data->D, dims_sub, data->dims_in); // optr and iptr same size regardless if do_circdiff true/false // if (data->do_circdiff) // out = 2*in; // out(..,1:(end-1),..) = out(..,1:(end-1),..) - in(..,2:end,..) // out(..,2:end,..) = out(..,2:end,..) - in(..,1:(end-1),..) // out(..,end,..) = out(..,end,..) - in(..,1,..) // out(..,1,..) = out(..,1,..) - in(..,end,..) // // else // out(..,1,..) = in(..,1,..) // out(..,end,..) = in(..,end,..) // out(..,2:(end-1),..) = 2*in(..,2:(end-1),..) // out(..,1:(end-1),..) = out(..,1:(end-1),..) - in(..,2:end,..) // out(..,2:end,..) = out(..,2:end,..) - in(..,1:(end-1),..) // if (data->do_circdiff) { md_zsmul2(data->D, data->dims_in, data->strides_in, optr, data->strides_in, iptr, 2.); dims_sub[d] = (nx - 1); offset = data->strides_in[d] / CFL_SIZE; // out(..,1:(end-1),..) = out(..,1:(end-1),..) - in(..,2:end,..) md_zsub2(data->D, dims_sub, data->strides_in, optr, data->strides_in, optr, data->strides_in, iptr + offset); // out(..,2:end,..) = out(..,2:end,..) - in(..,1:(end-1),..) md_zsub2(data->D, dims_sub, data->strides_in, optr + offset, data->strides_in, optr + offset, data->strides_in, iptr); dims_sub[d] = 1; offset = (nx - 1) * data->strides_in[d] / CFL_SIZE; // out(..,1,..) = out(..,1,..) - in(..,end,..) md_zsub2(data->D, dims_sub, data->strides_in, optr, data->strides_in, optr, data->strides_in, iptr + offset); // out(..,end,..) = out(..,end,..) - in(..,1,..) md_zsub2(data->D, dims_sub, data->strides_in, optr+offset, data->strides_in, optr+offset, data->strides_in, iptr); } else { dims_sub[d] = 1; offset = (nx - 1) * data->strides_in[d] / CFL_SIZE; // out(..,1,..) = in(..,1,..) md_copy2(data->D, dims_sub, data->strides_in, optr, data->strides_in, iptr, CFL_SIZE); // out(..,end,..) = in(..,end,..) md_copy2(data->D, dims_sub, data->strides_in, optr + offset, data->strides_in, iptr + offset, CFL_SIZE); dims_sub[d] = nx - 2; offset = data->strides_in[d] / CFL_SIZE; // out(..,2:(end-1),..) = 2*in(..,2:(end-1),..) md_zsmul2(data->D, dims_sub, data->strides_in, optr + offset, data->strides_in, iptr + offset, 2.); dims_sub[d] = nx - 1; offset = data->strides_in[d] / CFL_SIZE; // out(..,1:(end-1),..) = out(..,1:(end-1),..) - in(..,2:end,..) md_zsub2(data->D, dims_sub, data->strides_in, optr, data->strides_in, optr, data->strides_in, iptr + offset); // out(..,2:end,..) = out(..,2:end,..) - in(..,1:(end-1),..) md_zsub2(data->D, dims_sub, data->strides_in, optr + offset, data->strides_in, optr + offset, data->strides_in, iptr); } } static void zfinitediff_del(const linop_data_t* _data) { const auto data = CAST_DOWN(zfinitediff_data, _data); xfree(data->dims_in); xfree(data->strides_in); xfree(data->dims_adj); xfree(data->strides_adj); xfree(data); } const struct linop_s* linop_zfinitediff_create(unsigned int D, const long dims[D], long diffdim, bool circular) { PTR_ALLOC(struct zfinitediff_data, data); SET_TYPEID(zfinitediff_data, data); data->D = D; data->dim_diff = diffdim; data->do_circdiff = circular; data->dims_in = *TYPE_ALLOC(long[D]); data->dims_adj = *TYPE_ALLOC(long[D]); data->strides_in = *TYPE_ALLOC(long[D]); data->strides_adj = *TYPE_ALLOC(long[D]); md_copy_dims(D, data->dims_in, dims); md_copy_dims(D, data->dims_adj, dims); md_calc_strides(D, data->strides_in, data->dims_in, CFL_SIZE); if (!data->do_circdiff) data->dims_adj[data->dim_diff] -= 1; md_calc_strides(D, data->strides_adj, data->dims_adj, CFL_SIZE); const long* dims_adj = data->dims_adj; const long* dims_in = data->dims_in; return linop_create(D, dims_adj, D, dims_in, CAST_UP(PTR_PASS(data)), zfinitediff_apply, zfinitediff_adjoint, zfinitediff_normal, NULL, zfinitediff_del); } bart-0.5.00/src/linops/finite_diff.h000066400000000000000000000033151353046746100172510ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __FINITE_DIFF #define __FINITE_DIFF #include "misc/cppwrap.h" extern void md_zfinitediff(unsigned int D, const long dim[__VLA(D)], unsigned int flags, _Bool snip, _Complex float* optr, const _Complex float* iptr); extern void md_zfinitediff2(unsigned int D, const long dim[__VLA(D)], unsigned int flags, _Bool snip, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zcumsum(unsigned int D, const long dim[__VLA(D)], unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zcumsum2(unsigned int D, const long dim[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); struct linop_s; extern const struct linop_s* linop_finitediff_create(unsigned int D, const long dim[__VLA(D)], const unsigned long flags, _Bool snip); extern void fd_proj_noninc(const struct linop_s* o, _Complex float* optr, const _Complex float* iptr); /** * Circular finite difference operator * (without "snipping" or first elements) * * @param D number of dimensions * @param dim dimensions * @param diffdim specifies the direction to perform the operation * @param circular indicates whether it a circular operation * * Joseph Y Cheng (jycheng@stanford.edu) */ const struct linop_s* linop_zfinitediff_create(unsigned int D, const long dims[__VLA(D)], const long diffdim, _Bool circular); #include "misc/cppwrap.h" #endif bart-0.5.00/src/linops/fmac.c000066400000000000000000000076161353046746100157140ustar00rootroot00000000000000/* Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016-2018 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif //#include "num/iovec.h" #include "linops/linop.h" #include "misc/misc.h" #include "fmac.h" struct fmac_data { INTERFACE(linop_data_t); unsigned int N; long *dims; long *idims; long *istrs; long *odims; long *ostrs; long *tdims; long *tstrs; const complex float* tensor; #ifdef USE_CUDA const complex float* gpu_tensor; #endif }; static DEF_TYPEID(fmac_data); #ifdef USE_CUDA static const complex float* get_tensor(const struct fmac_data* data, bool gpu) { const complex float* tensor = data->tensor; if (gpu) { if (NULL == data->gpu_tensor) ((struct fmac_data*)data)->gpu_tensor = md_gpu_move(data->N, data->tdims, data->tensor, CFL_SIZE); tensor = data->gpu_tensor; } return tensor; } #endif static void fmac_free_data(const linop_data_t* _data) { auto data = CAST_DOWN(fmac_data, _data); #ifdef USE_CUDA if (NULL != data->gpu_tensor) md_free((void*)data->gpu_tensor); #endif xfree(data->dims); xfree(data->idims); xfree(data->istrs); xfree(data->odims); xfree(data->ostrs); xfree(data->tdims); xfree(data->tstrs); xfree(data); } static void fmac_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(fmac_data, _data); #ifdef USE_CUDA const complex float* tensor = get_tensor(data, cuda_ondevice(src)); #else const complex float* tensor = data->tensor; #endif md_clear2(data->N, data->odims, data->ostrs, dst, CFL_SIZE); md_zfmac2(data->N, data->dims, data->ostrs, dst, data->istrs, src, data->tstrs, tensor); } static void fmac_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(fmac_data, _data); #ifdef USE_CUDA const complex float* tensor = get_tensor(data, cuda_ondevice(src)); #else const complex float* tensor = data->tensor; #endif md_clear2(data->N, data->idims, data->istrs, dst, CFL_SIZE); md_zfmacc2(data->N, data->dims, data->istrs, dst, data->ostrs, src, data->tstrs, tensor); } static void fmac_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { struct fmac_data* data = CAST_DOWN(fmac_data, _data); complex float* tmp = md_alloc_sameplace(data->N, data->odims, CFL_SIZE, dst); fmac_apply(_data, tmp, src); fmac_adjoint(_data, dst, tmp); md_free(tmp); } const struct linop_s* linop_fmac_create(unsigned int N, const long dims[N], unsigned int oflags, unsigned int iflags, unsigned int tflags, const complex float* tensor) { PTR_ALLOC(struct fmac_data, data); SET_TYPEID(fmac_data, data); data->N = N; data->dims = *TYPE_ALLOC(long[N]); md_copy_dims(N, data->dims, dims); data->idims = *TYPE_ALLOC(long[N]); data->istrs = *TYPE_ALLOC(long[N]); md_select_dims(N, ~iflags, data->idims, dims); md_calc_strides(N, data->istrs, data->idims, CFL_SIZE); data->odims = *TYPE_ALLOC(long[N]); data->ostrs = *TYPE_ALLOC(long[N]); md_select_dims(N, ~oflags, data->odims, dims); md_calc_strides(N, data->ostrs, data->odims, CFL_SIZE); data->tstrs = *TYPE_ALLOC(long[N]); data->tdims = *TYPE_ALLOC(long[N]); md_select_dims(N, ~tflags, data->tdims, dims); md_calc_strides(N, data->tstrs, data->tdims, CFL_SIZE); data->tensor = tensor; #ifdef USE_CUDA data->gpu_tensor = NULL; #endif long odims[N]; md_copy_dims(N, odims, data->odims); long idims[N]; md_copy_dims(N, idims, data->idims); return linop_create(N, odims, N, idims, CAST_UP(PTR_PASS(data)), fmac_apply, fmac_adjoint, fmac_normal, NULL, fmac_free_data); } bart-0.5.00/src/linops/fmac.h000066400000000000000000000003321353046746100157050ustar00rootroot00000000000000 #include struct linop_s; extern const struct linop_s* linop_fmac_create(unsigned int N, const long dims[N], unsigned int oflags, unsigned int iflags, unsigned int flags, const complex float* tensor); bart-0.5.00/src/linops/grad.c000066400000000000000000000077501353046746100157220ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2019 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "linops/linop.h" #include "misc/misc.h" #include "grad.h" static void grad_dims(unsigned int D, long dims2[D], int d, unsigned int flags, const long dims[D]) { md_copy_dims(D, dims2, dims); assert(1 == dims[d]); assert(!MD_IS_SET(flags, d)); dims2[d] = bitcount(flags); } static void grad_op(unsigned int D, const long dims[D], int d, unsigned int flags, complex float* out, const complex float* in) { unsigned int N = bitcount(flags); assert(N == dims[d]); assert(!MD_IS_SET(flags, d)); long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); long dims1[D]; md_select_dims(D, ~MD_BIT(d), dims1, dims); long strs1[D]; md_calc_strides(D, strs1, dims1, CFL_SIZE); unsigned int flags2 = flags; for (unsigned int i = 0; i < N; i++) { unsigned int lsb = ffs(flags2) - 1; flags2 = MD_CLEAR(flags2, lsb); md_zfdiff2(D, dims1, lsb, strs, (void*)out + i * strs[d], strs1, in); } assert(0 == flags2); } static void grad_adjoint(unsigned int D, const long dims[D], int d, unsigned int flags, complex float* out, const complex float* in) { unsigned int N = bitcount(flags); assert(N == dims[d]); assert(!MD_IS_SET(flags, d)); long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); long dims1[D]; md_select_dims(D, ~MD_BIT(d), dims1, dims); long strs1[D]; md_calc_strides(D, strs1, dims1, CFL_SIZE); unsigned int flags2 = flags; complex float* tmp = md_alloc_sameplace(D, dims1, CFL_SIZE, out); md_clear(D, dims1, out, CFL_SIZE); md_clear(D, dims1, tmp, CFL_SIZE); for (unsigned int i = 0; i < N; i++) { unsigned int lsb = ffs(flags2) - 1; flags2 = MD_CLEAR(flags2, lsb); md_zfdiff_backwards2(D, dims1, lsb, strs1, tmp, strs, (void*)in + i * strs[d]); md_zadd(D, dims1, out, out, tmp); } md_free(tmp); assert(0 == flags2); } struct grad_s { INTERFACE(linop_data_t); int N; int d; long* dims; unsigned long flags; }; static DEF_TYPEID(grad_s); static void grad_op_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(grad_s, _data); grad_op(data->N, data->dims, data->d, data->flags, dst, src); } static void grad_op_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(grad_s, _data); grad_adjoint(data->N, data->dims, data->d, data->flags, dst, src); } static void grad_op_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(grad_s, _data); complex float* tmp = md_alloc_sameplace(data->N, data->dims, CFL_SIZE, dst); // this could be implemented more efficiently grad_op(data->N, data->dims, data->d, data->flags, tmp, src); grad_adjoint(data->N, data->dims, data->d, data->flags, dst, tmp); md_free(tmp); } static void grad_op_free(const linop_data_t* _data) { const auto data = CAST_DOWN(grad_s, _data); xfree(data->dims); xfree(data); } struct linop_s* linop_grad_create(long N, const long dims[N], int d, unsigned int flags) { PTR_ALLOC(struct grad_s, data); SET_TYPEID(grad_s, data); int NO = N; if (N == d) { // as a special case, id d is one after the last dimensions, // we extend the output dimensions by one. NO++; } else { assert(1 == dims[d]); } long dims2[NO]; md_copy_dims(N, dims2, dims); dims2[d] = 1; grad_dims(NO, dims2, d, flags, dims2); data->N = NO; data->d = d; data->flags = flags; data->dims = *TYPE_ALLOC(long[N + 1]); md_copy_dims(NO, data->dims, dims2); return linop_create(NO, dims2, N, dims, CAST_UP(PTR_PASS(data)), grad_op_apply, grad_op_adjoint, grad_op_normal, NULL, grad_op_free); } bart-0.5.00/src/linops/grad.h000066400000000000000000000005431353046746100157200ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" extern struct linop_s* linop_grad_create(long N, const long dims[__VLA(N)], int d, unsigned int flags); #include "misc/cppwrap.h" bart-0.5.00/src/linops/linop.c000066400000000000000000000360421353046746100161220ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2019 Martin Uecker * 2014 Frank Ong */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "num/ops_p.h" #include "num/ops.h" #include "misc/misc.h" #include "misc/shrdptr.h" #include "misc/debug.h" #include "misc/shrdptr.h" #include "linop.h" struct shared_data_s { INTERFACE(operator_data_t); linop_data_t* data; del_fun_t del; struct shared_ptr_s sptr; union { lop_fun_t apply; lop_p_fun_t apply_p; } u; }; static DEF_TYPEID(shared_data_s); static void shared_del(const operator_data_t* _data) { auto data = CAST_DOWN(shared_data_s, _data); shared_ptr_destroy(&data->sptr); xfree(data); } static void shared_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { auto data = CAST_DOWN(shared_data_s, _data); assert(2 == N); debug_trace("ENTER %p\n", data->u.apply); data->u.apply(data->data, args[0], args[1]); debug_trace("LEAVE %p\n", data->u.apply); } static void shared_apply_p(const operator_data_t* _data, float lambda, complex float* dst, const complex float* src) { auto data = CAST_DOWN(shared_data_s, _data); debug_trace("ENTER %p\n", data->u.apply_p); data->u.apply_p(data->data, lambda, dst, src); debug_trace("LEAVE %p\n", data->u.apply_p); } static void sptr_del(const struct shared_ptr_s* p) { auto data = CONTAINER_OF(p, struct shared_data_s, sptr); data->del(data->data); } /** * Create a linear operator (with strides) */ struct linop_s* linop_create2(unsigned int ON, const long odims[ON], const long ostrs[ON], unsigned int IN, const long idims[IN], const long istrs[IN], linop_data_t* data, lop_fun_t forward, lop_fun_t adjoint, lop_fun_t normal, lop_p_fun_t norm_inv, del_fun_t del) { PTR_ALLOC(struct linop_s, lo); struct shared_data_s* shared_data[4]; for (unsigned int i = 0; i < 4; i++) { shared_data[i] = TYPE_ALLOC(struct shared_data_s); SET_TYPEID(shared_data_s, shared_data[i]); } for (unsigned int i = 0; i < 4; i++) { shared_data[i]->data = data; shared_data[i]->del = del; if (0 == i) shared_ptr_init(&shared_data[i]->sptr, sptr_del); else shared_ptr_copy(&shared_data[i]->sptr, &shared_data[0]->sptr); } shared_data[0]->u.apply = forward; shared_data[1]->u.apply = adjoint; shared_data[2]->u.apply = normal; shared_data[3]->u.apply_p = norm_inv; assert((NULL != forward)); assert((NULL != adjoint)); lo->forward = operator_create2(ON, odims, ostrs, IN, idims, istrs, CAST_UP(shared_data[0]), shared_apply, shared_del); lo->adjoint = operator_create2(IN, idims, istrs, ON, odims, ostrs, CAST_UP(shared_data[1]), shared_apply, shared_del); if (NULL != normal) { lo->normal = operator_create2(IN, idims, istrs, IN, idims, istrs, CAST_UP(shared_data[2]), shared_apply, shared_del); } else { shared_ptr_destroy(&shared_data[2]->sptr); xfree(shared_data[2]); #if 0 lo->normal = NULL; #else lo->normal = operator_chain(lo->forward, lo->adjoint); #endif } if (NULL != norm_inv) { lo->norm_inv = operator_p_create2(IN, idims, istrs, IN, idims, istrs, CAST_UP(shared_data[3]), shared_apply_p, shared_del); } else { shared_ptr_destroy(&shared_data[3]->sptr); xfree(shared_data[3]); lo->norm_inv = NULL; } return PTR_PASS(lo); } /** * Create a linear operator (without strides) * * @param N number of dimensions * @param odims dimensions of output (codomain) * @param idims dimensions of input (domain) * @param data data for applying the operator * @param forward function for applying the forward operation, A * @param adjoint function for applying the adjoint operation, A^H * @param normal function for applying the normal equations operation, A^H A * @param norm_inv function for applying the pseudo-inverse operation, (A^H A + mu I)^-1 * @param del function for freeing the data */ struct linop_s* linop_create(unsigned int ON, const long odims[ON], unsigned int IN, const long idims[IN], linop_data_t* data, lop_fun_t forward, lop_fun_t adjoint, lop_fun_t normal, lop_p_fun_t norm_inv, del_fun_t del) { long ostrs[ON]; long istrs[IN]; md_calc_strides(ON, ostrs, odims, CFL_SIZE); md_calc_strides(IN, istrs, idims, CFL_SIZE); return linop_create2(ON, odims, ostrs, IN, idims, istrs, data, forward, adjoint, normal, norm_inv, del); } /** * Return the data associated with the linear operator * * @param ptr linear operator */ const linop_data_t* linop_get_data(const struct linop_s* ptr) { auto sdata = CAST_MAYBE(shared_data_s, operator_get_data(ptr->forward)); return sdata == NULL ? NULL : sdata->data; } /** * Make a copy of a linear operator * @param x linear operator */ extern const struct linop_s* linop_clone(const struct linop_s* x) { PTR_ALLOC(struct linop_s, lo); lo->forward = operator_ref(x->forward); lo->adjoint = operator_ref(x->adjoint); lo->normal = operator_ref(x->normal); lo->norm_inv = operator_p_ref(x->norm_inv); return PTR_PASS(lo); } /** * Apply the forward operation of a linear operator: y = A x * Checks that dimensions are consistent for the linear operator * * @param op linear operator * @param DN number of destination dimensions * @param ddims dimensions of the output (codomain) * @param dst output data * @param SN number of source dimensions * @param sdims dimensions of the input (domain) * @param src input data */ void linop_forward(const struct linop_s* op, unsigned int DN, const long ddims[DN], complex float* dst, unsigned int SN, const long sdims[SN], const complex float* src) { assert(op->forward); operator_apply(op->forward, DN, ddims, dst, SN, sdims, src); } /** * Apply the adjoint operation of a linear operator: y = A^H x * Checks that dimensions are consistent for the linear operator * * @param op linear operator * @param DN number of destination dimensions * @param ddims dimensions of the output (domain) * @param dst output data * @param SN number of source dimensions * @param sdims dimensions of the input (codomain) * @param src input data */ void linop_adjoint(const struct linop_s* op, unsigned int DN, const long ddims[DN], complex float* dst, unsigned int SN, const long sdims[SN], const complex float* src) { assert(op->adjoint); operator_apply(op->adjoint, DN, ddims, dst, SN, sdims, src); } /** * Apply the pseudo-inverse operation of a linear operator: x = (A^H A + lambda I)^-1 A^H y * Checks that dimensions are consistent for the linear operator * * @param op linear operator * @param lambda regularization parameter * @param DN number of destination dimensions * @param ddims dimensions of the output (domain) * @param dst output data * @param SN number of source dimensions * @param sdims dimensions of the input (codomain) * @param src input data */ void linop_pseudo_inv(const struct linop_s* op, float lambda, unsigned int DN, const long ddims[DN], complex float* dst, unsigned int SN, const long sdims[SN], const complex float* src) { complex float* adj = md_alloc_sameplace(DN, ddims, CFL_SIZE, dst); linop_adjoint(op, DN, ddims, adj, SN, sdims, src); assert(op->norm_inv); operator_p_apply(op->norm_inv, lambda, DN, ddims, dst, DN, ddims, adj); md_free(adj); } /** * Apply the normal equations operation of a linear operator: y = A^H A x * Checks that dimensions are consistent for the linear operator * * @param op linear operator * @param N number of dimensions * @param dims dimensions * @param dst output data * @param src input data */ void linop_normal(const struct linop_s* op, unsigned int N, const long dims[N], complex float* dst, const complex float* src) { assert(op->normal); operator_apply(op->normal, N, dims, dst, N, dims, src); } /** * Apply the forward operation of a linear operator: y = A x * Does not check that the dimensions are consistent for the linear operator * * @param op linear operator * @param dst output data * @param src input data */ void linop_forward_unchecked(const struct linop_s* op, complex float* dst, const complex float* src) { assert(op->forward); operator_apply_unchecked(op->forward, dst, src); } /** * Apply the adjoint operation of a linear operator: y = A^H x * Does not check that the dimensions are consistent for the linear operator * * @param op linear operator * @param dst output data * @param src input data */ void linop_adjoint_unchecked(const struct linop_s* op, complex float* dst, const complex float* src) { assert(op->adjoint); operator_apply_unchecked(op->adjoint, dst, src); } /** * Apply the normal equations operation of a linear operator: y = A^H A x * Does not check that the dimensions are consistent for the linear operator * * @param op linear operator * @param dst output data * @param src input data */ void linop_normal_unchecked(const struct linop_s* op, complex float* dst, const complex float* src) { assert(op->normal); operator_apply_unchecked(op->normal, dst, src); } /** * Apply the pseudo-inverse operation of a linear operator: y = (A^H A + lambda I)^-1 x * Does not check that the dimensions are consistent for the linear operator * * @param op linear operator * @param lambda regularization parameter * @param dst output data * @param src input data */ void linop_norm_inv_unchecked(const struct linop_s* op, float lambda, complex float* dst, const complex float* src) { operator_p_apply_unchecked(op->norm_inv, lambda, dst, src); } /** * Return the dimensions and strides of the domain of a linear operator * * @param op linear operator */ const struct iovec_s* linop_domain(const struct linop_s* op) { return operator_domain(op->forward); } /** * Return the dimensions and strides of the codomain of a linear operator * * @param op linear operator */ const struct iovec_s* linop_codomain(const struct linop_s* op) { return operator_codomain(op->forward); } struct linop_s* linop_null_create2(unsigned int N, const long odims[N], const long ostrs[N], const long idims[N], const long istrs[N]) { PTR_ALLOC(struct linop_s, c); const struct operator_s* nudo = operator_null_create2(N, idims, istrs); const struct operator_s* zedo = operator_zero_create2(N, idims, istrs); const struct operator_s* nuco = operator_null_create2(N, odims, ostrs); const struct operator_s* zeco = operator_zero_create2(N, odims, ostrs); c->forward = operator_combi_create(2, MAKE_ARRAY(zeco, nudo)); c->adjoint = operator_combi_create(2, MAKE_ARRAY(zedo, nuco)); c->normal = operator_combi_create(2, MAKE_ARRAY(zedo, nudo)); c->norm_inv = NULL; operator_free(nudo); operator_free(zedo); operator_free(nuco); operator_free(zeco); return PTR_PASS(c); } struct linop_s* linop_null_create(unsigned int N, const long odims[N], const long idims[N]) { return linop_null_create2(N, odims, MD_STRIDES(N, odims, CFL_SIZE), idims, MD_STRIDES(N, idims, CFL_SIZE)); } /** * Create chain of linear operators. * C = B A * C^H = A^H B^H * C^H C = A^H B^H B A */ struct linop_s* linop_chain(const struct linop_s* a, const struct linop_s* b) { PTR_ALLOC(struct linop_s, c); c->forward = operator_chain(a->forward, b->forward); c->adjoint = operator_chain(b->adjoint, a->adjoint); if (NULL == b->normal) { c->normal = operator_chain(c->forward, c->adjoint); } else { const struct operator_s* top = operator_chain(b->normal, a->adjoint); c->normal = operator_chain(a->forward, top); operator_free(top); } c->norm_inv = NULL; return PTR_PASS(c); } struct linop_s* linop_chain_FF(const struct linop_s* a, const struct linop_s* b) { struct linop_s* x = linop_chain(a, b); linop_free(a); linop_free(b); return x; } struct linop_s* linop_chainN(unsigned int N, struct linop_s* a[N]) { assert(N > 0); if (1 == N) return a[0]; return linop_chain(a[0], linop_chainN(N - 1, a + 1)); // FIXME: free intermed. } struct linop_s* linop_stack(int D, int E, const struct linop_s* a, const struct linop_s* b) { PTR_ALLOC(struct linop_s, c); c->forward = operator_stack(D, E, a->forward, b->forward); c->adjoint = operator_stack(E, D, b->adjoint, a->adjoint); const struct operator_s* an = a->normal; if (NULL == an) an = operator_chain(a->forward, a->adjoint); const struct operator_s* bn = b->normal; if (NULL == bn) bn = operator_chain(b->forward, b->adjoint); c->normal = operator_stack(D, D, an, bn); c->norm_inv = NULL; return PTR_PASS(c); } struct linop_s* linop_loop(unsigned int D, const long dims[D], struct linop_s* op) { PTR_ALLOC(struct linop_s, op2); op2->forward = operator_loop(D, dims, op->forward); op2->adjoint = operator_loop(D, dims, op->adjoint); op2->normal = (NULL == op->normal) ? NULL : operator_loop(D, dims, op->normal); op2->norm_inv = NULL; // FIXME return op2; } /** * Free the linear operator and associated data, * Note: only frees the data if its reference count is zero * * @param op linear operator */ void linop_free(const struct linop_s* op) { if (NULL == op) return; operator_free(op->forward); operator_free(op->adjoint); operator_free(op->normal); operator_p_free(op->norm_inv); xfree(op); } struct plus_data_s { INTERFACE(linop_data_t); const struct linop_s* a; const struct linop_s* b; }; static DEF_TYPEID(plus_data_s); static void plus_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(plus_data_s, _data); auto iov = linop_codomain(data->a); complex float* tmp = md_alloc_sameplace(iov->N, iov->dims, iov->size, dst); linop_forward_unchecked(data->a, dst, src); linop_forward_unchecked(data->b, tmp, src); md_zadd(iov->N, iov->dims, dst, dst, tmp); md_free(tmp); } static void plus_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(plus_data_s, _data); auto iov = linop_domain(data->a); complex float* tmp = md_alloc_sameplace(iov->N, iov->dims, iov->size, dst); linop_adjoint_unchecked(data->a, dst, src); linop_adjoint_unchecked(data->b, tmp, src); md_zadd(iov->N, iov->dims, dst, dst, tmp); md_free(tmp); } static void plus_free(const linop_data_t* _data) { auto data = CAST_DOWN(plus_data_s, _data); linop_free(data->a); linop_free(data->b); xfree(data); } struct linop_s* linop_plus(const struct linop_s* a, const struct linop_s* b) { #if 1 // detect null operations and just clone if (operator_zero_or_null_p(a->forward)) return (struct linop_s*)linop_clone(b); if (operator_zero_or_null_p(b->forward)) return (struct linop_s*)linop_clone(a); #endif auto bdo = linop_domain(b); assert(CFL_SIZE == bdo->size); iovec_check(linop_domain(a), bdo->N, bdo->dims, bdo->strs); auto bco = linop_codomain(b); assert(CFL_SIZE == bco->size); iovec_check(linop_codomain(a), bco->N, bco->dims, bco->strs); PTR_ALLOC(struct plus_data_s, data); SET_TYPEID(plus_data_s, data); data->a = linop_clone(a); data->b = linop_clone(b); return linop_create(bco->N, bco->dims, bdo->N, bdo->dims, CAST_UP(PTR_PASS(data)), plus_apply, plus_adjoint, NULL, NULL, plus_free); } bart-0.5.00/src/linops/linop.h000066400000000000000000000074011353046746100161240ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #ifndef __LINOP_H #define __LINOP_H #include "misc/cppwrap.h" #include "misc/types.h" extern TYPEID linop_data_s; typedef struct linop_data_s { TYPEID* TYPEID; } linop_data_t; typedef void (*lop_fun_t)(const linop_data_t* _data, complex float* dst, const complex float* src); typedef void (*lop_p_fun_t)(const linop_data_t* _data, float lambda, complex float* dst, const complex float* src); typedef void (*del_fun_t)(const linop_data_t* _data); struct operator_s; struct operator_p_s; struct linop_s { const struct operator_s* forward; const struct operator_s* adjoint; const struct operator_s* normal; const struct operator_p_s* norm_inv; }; extern struct linop_s* linop_create(unsigned int ON, const long odims[__VLA(ON)], unsigned int IN, const long idims[__VLA(IN)], linop_data_t* data, lop_fun_t forward, lop_fun_t adjoint, lop_fun_t normal, lop_p_fun_t norm_inv, del_fun_t); extern struct linop_s* linop_create2(unsigned int ON, const long odims[__VLA(ON)], const long ostr[__VLA(ON)], unsigned int IN, const long idims[__VLA(IN)], const long istrs[__VLA(IN)], linop_data_t* data, lop_fun_t forward, lop_fun_t adjoint, lop_fun_t normal, lop_p_fun_t norm_inv, del_fun_t); extern const linop_data_t* linop_get_data(const struct linop_s* ptr); extern void linop_free(const struct linop_s* op); extern void linop_forward(const struct linop_s* op, unsigned int DN, const long ddims[__VLA(DN)], complex float* dst, unsigned int SN, const long sdims[__VLA(SN)], const complex float* src); extern void linop_adjoint(const struct linop_s* op, unsigned int DN, const long ddims[__VLA(DN)], complex float* dst, unsigned int SN, const long sdims[__VLA(SN)], const complex float* src); extern void linop_normal(const struct linop_s* op, unsigned int N, const long dims[__VLA(N)], complex float* dst, const complex float* src); extern void linop_pseudo_inv(const struct linop_s* op, float lambda, unsigned int DN, const long ddims[__VLA(DN)], complex float* dst, unsigned int SN, const long sdims[__VLA(SN)], const complex float* src); extern void linop_forward_unchecked(const struct linop_s* op, complex float* dst, const complex float* src); extern void linop_adjoint_unchecked(const struct linop_s* op, complex float* dst, const complex float* src); extern void linop_normal_unchecked(const struct linop_s* op, complex float* dst, const complex float* src); extern void linop_norm_inv_unchecked(const struct linop_s* op, float lambda, complex float* dst, const complex float* src); extern struct linop_s* linop_chain(const struct linop_s* a, const struct linop_s* b); extern struct linop_s* linop_chainN(unsigned int N, struct linop_s* x[N]); extern struct linop_s* linop_chain_FF(const struct linop_s* a, const struct linop_s* b); extern struct linop_s* linop_stack(int D, int E, const struct linop_s* a, const struct linop_s* b); struct iovec_s; extern const struct iovec_s* linop_domain(const struct linop_s* x); extern const struct iovec_s* linop_codomain(const struct linop_s* x); extern const struct linop_s* linop_clone(const struct linop_s* x); extern struct linop_s* linop_loop(unsigned int D, const long dims[D], struct linop_s* op); extern struct linop_s* linop_null_create2(unsigned int N, const long odims[N], const long ostrs[N], const long idims[N], const long istrs[N]); extern struct linop_s* linop_null_create(unsigned int N, const long odims[N], const long idims[N]); extern struct linop_s* linop_plus(const struct linop_s* a, const struct linop_s* b); #include "misc/cppwrap.h" #endif // __LINOP_H bart-0.5.00/src/linops/lintest.c000066400000000000000000000063061353046746100164630ustar00rootroot00000000000000/* Copyright 2017-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include #include "misc/debug.h" #include "num/rand.h" #include "num/iovec.h" #include "num/multind.h" #include "num/flpmath.h" #include "linops/linop.h" #include "lintest.h" static float linop_test_adjoint_generic(const struct linop_s* op, bool rvc) { int N_dom = linop_domain(op)->N; int N_cod = linop_codomain(op)->N; long dims_dom[N_dom]; md_copy_dims(N_dom, dims_dom, linop_domain(op)->dims); long dims_cod[N_cod]; md_copy_dims(N_cod, dims_cod, linop_codomain(op)->dims); complex float* tmp1 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* tmp2 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* tmp3 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* tmp4 = md_alloc(N_dom, dims_dom, CFL_SIZE); md_gaussian_rand(N_dom, dims_dom, tmp1); if (rvc) md_zreal(N_dom, dims_dom, tmp1, tmp1); linop_forward_unchecked(op, tmp3, tmp1); md_gaussian_rand(N_cod, dims_cod, tmp2); if (rvc) md_zreal(N_dom, dims_cod, tmp2, tmp2); linop_adjoint_unchecked(op, tmp4, tmp2); complex float sc1 = md_zscalar(N_dom, dims_dom, tmp1, tmp4); complex float sc2 = md_zscalar(N_cod, dims_cod, tmp3, tmp2); md_free(tmp1); md_free(tmp2); md_free(tmp3); md_free(tmp4); debug_printf(DP_DEBUG4, "- %f%+fi - %f%+fi -\n", crealf(sc1), cimagf(sc1), crealf(sc2), cimagf(sc2)); return cabsf(sc1 - sc2); } float linop_test_adjoint(const struct linop_s* op) { return linop_test_adjoint_generic(op, false); } float linop_test_adjoint_real(const struct linop_s* op) { return linop_test_adjoint_generic(op, true); } float linop_test_normal(const struct linop_s* op) { int N_dom = linop_domain(op)->N; int N_cod = linop_codomain(op)->N; long dims_dom[N_dom]; md_copy_dims(N_dom, dims_dom, linop_domain(op)->dims); long dims_cod[N_cod]; md_copy_dims(N_cod, dims_cod, linop_codomain(op)->dims); complex float* tmp1 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* tmp2 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* tmp3 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* tmp4 = md_alloc(N_dom, dims_dom, CFL_SIZE); md_gaussian_rand(N_dom, dims_dom, tmp1); linop_forward_unchecked(op, tmp3, tmp1); linop_adjoint_unchecked(op, tmp4, tmp3); linop_normal_unchecked(op, tmp2, tmp1); float nrmse = md_znrmse(N_dom, dims_dom, tmp2, tmp4); md_free(tmp1); md_free(tmp2); md_free(tmp3); md_free(tmp4); return nrmse; } float linop_test_inverse(const struct linop_s* op) { int N_dom = linop_domain(op)->N; long dims_dom[N_dom]; md_copy_dims(N_dom, dims_dom, linop_domain(op)->dims); complex float* tmp1 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* tmp2 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* tmp3 = md_alloc(N_dom, dims_dom, CFL_SIZE); md_gaussian_rand(N_dom, dims_dom, tmp1); linop_normal_unchecked(op, tmp3, tmp1); linop_norm_inv_unchecked(op, 0., tmp2, tmp3); float nrmse = md_znrmse(N_dom, dims_dom, tmp2, tmp1); md_free(tmp1); md_free(tmp2); md_free(tmp3); return nrmse; } bart-0.5.00/src/linops/lintest.h000066400000000000000000000004041353046746100164610ustar00rootroot00000000000000 struct linop_s; extern float linop_test_adjoint(const struct linop_s* op); extern float linop_test_adjoint_real(const struct linop_s* op); extern float linop_test_normal(const struct linop_s* op); extern float linop_test_inverse(const struct linop_s* op); bart-0.5.00/src/linops/realval.c000066400000000000000000000023441353046746100164250ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2018 Martin Uecker */ #include #include "misc/misc.h" #include "num/flpmath.h" #include "num/multind.h" #include "linops/linop.h" #include "realval.h" struct rvc_s { INTERFACE(linop_data_t); unsigned int N; const long* dims; }; static DEF_TYPEID(rvc_s); static void rvc_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(rvc_s, _data); md_zreal(data->N, data->dims, dst, src); } static void rvc_free(const linop_data_t* _data) { const auto data = CAST_DOWN(rvc_s, _data); xfree(data->dims); xfree(data); } struct linop_s* linop_realval_create(unsigned int N, const long dims[N]) { PTR_ALLOC(struct rvc_s, data); SET_TYPEID(rvc_s, data); PTR_ALLOC(long[N], dims2); md_copy_dims(N, *dims2, dims); data->N = N; data->dims = *PTR_PASS(dims2); return linop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), rvc_apply, rvc_apply, rvc_apply, NULL, rvc_free); } bart-0.5.00/src/linops/realval.h000066400000000000000000000002201353046746100164210ustar00rootroot00000000000000 #include "misc/cppwrap.h" extern struct linop_s* linop_realval_create(unsigned int N, const long dims[__VLA(N)]); #include "misc/cppwrap.h" bart-0.5.00/src/linops/sampling.c000066400000000000000000000047621353046746100166170ustar00rootroot00000000000000/* Copyright 2014,2017. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2018 Martin Uecker * 2017 Jon Tamir */ #include #include "misc/mri.h" #include "misc/misc.h" #include "num/flpmath.h" #include "num/multind.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "linops/linop.h" #include "sampling.h" struct sampling_data_s { INTERFACE(linop_data_t); long dims[DIMS]; long strs[DIMS]; long pat_dims[DIMS]; long pat_strs[DIMS]; complex float* pattern; #ifdef USE_CUDA const complex float* gpu_pattern; #endif }; static DEF_TYPEID(sampling_data_s); #ifdef USE_CUDA static const complex float* get_pat(const struct sampling_data_s* data, bool gpu) { const complex float* pattern = data->pattern; if (gpu) { if (NULL == data->gpu_pattern) ((struct sampling_data_s*)data)->gpu_pattern = md_gpu_move(DIMS, data->pat_dims, data->pattern, CFL_SIZE); pattern = data->gpu_pattern; } return pattern; } #endif static void sampling_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(sampling_data_s, _data); #ifdef USE_CUDA const complex float* pattern = get_pat(data, cuda_ondevice(src)); #else const complex float* pattern = data->pattern; #endif md_zmul2(DIMS, data->dims, data->strs, dst, data->strs, src, data->pat_strs, pattern); } static void sampling_free(const linop_data_t* _data) { const auto data = CAST_DOWN(sampling_data_s, _data); #ifdef USE_CUDA if (NULL != data->gpu_pattern) { md_free((void*)data->gpu_pattern); } #endif xfree(data); } struct linop_s* linop_sampling_create(const long dims[DIMS], const long pat_dims[DIMS], const complex float* pattern) { PTR_ALLOC(struct sampling_data_s, data); SET_TYPEID(sampling_data_s, data); md_copy_dims(DIMS, data->pat_dims, pat_dims); md_select_dims(DIMS, ~MAPS_FLAG, data->dims, dims); // dimensions of kspace md_calc_strides(DIMS, data->strs, data->dims, CFL_SIZE); md_calc_strides(DIMS, data->pat_strs, data->pat_dims, CFL_SIZE); data->pattern = (complex float*)pattern; #ifdef USE_CUDA data->gpu_pattern = NULL; #endif const long* dims2 = data->dims; return linop_create(DIMS, dims2, DIMS, dims2, CAST_UP(PTR_PASS(data)), sampling_apply, sampling_apply, sampling_apply, NULL, sampling_free); } bart-0.5.00/src/linops/sampling.h000066400000000000000000000002311353046746100166070ustar00rootroot00000000000000 #include "misc/mri.h" extern struct linop_s* linop_sampling_create(const long dims[DIMS], const long pat_dims[DIMS], const complex float* pattern); bart-0.5.00/src/linops/someops.c000066400000000000000000000753551353046746100165000ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2018 Martin Uecker * 2014 Jonathan Tamir */ #include #include #include "misc/misc.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/wavelet.h" #include "num/conv.h" #include "num/ops.h" #include "num/iovec.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "linops/linop.h" #include "someops.h" struct cdiag_s { INTERFACE(linop_data_t); unsigned int N; const long* dims; const long* strs; const long* ddims; const long* dstrs; const complex float* diag; #ifdef USE_CUDA const complex float* gpu_diag; #endif bool rmul; }; static DEF_TYPEID(cdiag_s); static void cdiag_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(cdiag_s, _data); const complex float* diag = data->diag; #ifdef USE_CUDA if (cuda_ondevice(src)) { if (NULL == data->gpu_diag) ((struct cdiag_s*)data)->gpu_diag = md_gpu_move(data->N, data->ddims, data->diag, CFL_SIZE); diag = data->gpu_diag; } #endif (data->rmul ? md_zrmul2 : md_zmul2)(data->N, data->dims, data->strs, dst, data->strs, src, data->dstrs, diag); } static void cdiag_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(cdiag_s, _data); const complex float* diag = data->diag; #ifdef USE_CUDA if (cuda_ondevice(src)) { if (NULL == data->gpu_diag) ((struct cdiag_s*)data)->gpu_diag = md_gpu_move(data->N, data->ddims, data->diag, CFL_SIZE); diag = data->gpu_diag; } #endif (data->rmul ? md_zrmul2 : md_zmulc2)(data->N, data->dims, data->strs, dst, data->strs, src, data->dstrs, diag); } static void cdiag_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { cdiag_apply(_data, dst, src); cdiag_adjoint(_data, dst, dst); } static void cdiag_free(const linop_data_t* _data) { const auto data = CAST_DOWN(cdiag_s, _data); md_free(data->diag); #ifdef USE_CUDA md_free(data->gpu_diag); #endif xfree(data->ddims); xfree(data->dims); xfree(data->dstrs); xfree(data->strs); xfree(data); } static struct linop_s* linop_gdiag_create(unsigned int N, const long dims[N], unsigned int flags, const complex float* diag, bool rdiag) { PTR_ALLOC(struct cdiag_s, data); SET_TYPEID(cdiag_s, data); data->rmul = rdiag; data->N = N; PTR_ALLOC(long[N], ddims); PTR_ALLOC(long[N], dstrs); PTR_ALLOC(long[N], dims2); PTR_ALLOC(long[N], strs); md_select_dims(N, flags, *ddims, dims); md_calc_strides(N, *dstrs, *ddims, CFL_SIZE); md_copy_dims(N, *dims2, dims); md_calc_strides(N, *strs, dims, CFL_SIZE); data->dims = *PTR_PASS(dims2); data->strs = *PTR_PASS(strs); data->ddims = *PTR_PASS(ddims); data->dstrs = *PTR_PASS(dstrs); complex float* tmp = md_alloc(N, data->ddims, CFL_SIZE); md_copy(N, data->ddims, tmp, diag, CFL_SIZE); data->diag = tmp; #ifdef USE_CUDA data->gpu_diag = NULL; #endif return linop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), cdiag_apply, cdiag_adjoint, cdiag_normal, NULL, cdiag_free); } /** * Create a operator y = D x where D is a diagonal matrix * * @param N number of dimensions * @param dims input and output dimensions * @param flags bitmask specifiying the dimensions present in diag * @param diag diagonal matrix */ struct linop_s* linop_cdiag_create(unsigned int N, const long dims[N], unsigned int flags, const complex float* diag) { return linop_gdiag_create(N, dims, flags, diag, false); } /** * Create a operator y = D x where D is a diagonal matrix * * @param N number of dimensions * @param dims input and output dimensions * @param flags bitmask specifiying the dimensions present in diag * @param diag diagonal matrix */ struct linop_s* linop_rdiag_create(unsigned int N, const long dims[N], unsigned int flags, const complex float* diag) { return linop_gdiag_create(N, dims, flags, diag, true); } struct identity_data_s { INTERFACE(linop_data_t); const struct iovec_s* domain; }; static DEF_TYPEID(identity_data_s); static void identity_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(identity_data_s, _data); const struct iovec_s* domain = data->domain; md_copy2(domain->N, domain->dims, domain->strs, dst, domain->strs, src, CFL_SIZE); } static void identity_free(const linop_data_t* _data) { const auto data = CAST_DOWN(identity_data_s, _data); iovec_free(data->domain); xfree(data); } /** * Create an Identity linear operator: I x * @param N number of dimensions * @param dims dimensions of input (domain) */ struct linop_s* linop_identity_create(unsigned int N, const long dims[N]) { PTR_ALLOC(struct identity_data_s, data); SET_TYPEID(identity_data_s, data); data->domain = iovec_create(N, dims, CFL_SIZE); return linop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), identity_apply, identity_apply, identity_apply, NULL, identity_free); } struct resize_op_s { INTERFACE(linop_data_t); bool center; unsigned int N; const long* out_dims; const long* in_dims; }; static DEF_TYPEID(resize_op_s); static void resize_forward(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(resize_op_s, _data); (data->center ? md_resize_center : md_resize)(data->N, data->out_dims, dst, data->in_dims, src, CFL_SIZE); } static void resize_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(resize_op_s, _data); (data->center ? md_resize_center : md_resize)(data->N, data->in_dims, dst, data->out_dims, src, CFL_SIZE); } static void resize_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(resize_op_s, _data); complex float* tmp = md_alloc_sameplace(data->N, data->out_dims, CFL_SIZE, dst); resize_forward(_data, tmp, src); resize_adjoint(_data, dst, tmp); md_free(tmp); } static void resize_free(const linop_data_t* _data) { const auto data = CAST_DOWN(resize_op_s, _data); xfree(data->out_dims); xfree(data->in_dims); xfree(data); } static struct linop_s* linop_resize_generic_create(unsigned int N, const long out_dims[N], const long in_dims[N], bool center) { PTR_ALLOC(struct resize_op_s, data); SET_TYPEID(resize_op_s, data); data->center = center; data->N = N; data->out_dims = *TYPE_ALLOC(long[N]); data->in_dims = *TYPE_ALLOC(long[N]); md_copy_dims(N, (long*)data->out_dims, out_dims); md_copy_dims(N, (long*)data->in_dims, in_dims); return linop_create(N, out_dims, N, in_dims, CAST_UP(PTR_PASS(data)), resize_forward, resize_adjoint, resize_normal, NULL, resize_free); } /** * Create a resize linear operator: y = M x, * where M either crops or expands the the input dimensions to match the output dimensions. * Uses centered zero-padding and centered cropping * * @param N number of dimensions * @param out_dims output dimensions * @param in_dims input dimensions */ struct linop_s* linop_resize_create(unsigned int N, const long out_dims[N], const long in_dims[N]) { return linop_resize_generic_create(N, out_dims, in_dims, true); } struct linop_s* linop_resize_center_create(unsigned int N, const long out_dims[N], const long in_dims[N]) { return linop_resize_generic_create(N, out_dims, in_dims, true); } struct linop_s* linop_expand_create(unsigned int N, const long out_dims[N], const long in_dims[N]) { return linop_resize_generic_create(N, out_dims, in_dims, false); } struct extract_op_s { INTERFACE(linop_data_t); int N; const long* pos; const long* in_dims; const long* out_dims; }; static DEF_TYPEID(extract_op_s); static void extract_forward(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(extract_op_s, _data); md_clear(data->N, data->out_dims, dst, CFL_SIZE); md_copy_block(data->N, data->pos, data->out_dims, dst, data->in_dims, src, CFL_SIZE); } static void extract_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(extract_op_s, _data); md_clear(data->N, data->in_dims, dst, CFL_SIZE); md_copy_block(data->N, data->pos, data->in_dims, dst, data->out_dims, src, CFL_SIZE); } static void extract_free(const linop_data_t* _data) { const auto data = CAST_DOWN(extract_op_s, _data); xfree(data->out_dims); xfree(data->in_dims); xfree(data->pos); xfree(data); } extern struct linop_s* linop_extract_create(unsigned int N, const long pos[N], const long out_dims[N], const long in_dims[N]) { PTR_ALLOC(struct extract_op_s, data); SET_TYPEID(extract_op_s, data); data->N = N; data->pos = *TYPE_ALLOC(long[N]); data->out_dims = *TYPE_ALLOC(long[N]); data->in_dims = *TYPE_ALLOC(long[N]); md_copy_dims(N, (long*)data->pos, pos); md_copy_dims(N, (long*)data->out_dims, out_dims); md_copy_dims(N, (long*)data->in_dims, in_dims); return linop_create(N, out_dims, N, in_dims, CAST_UP(PTR_PASS(data)), extract_forward, extract_adjoint, NULL, NULL, extract_free); } struct reshape_op_s { INTERFACE(linop_data_t); unsigned int N; const long* dims; }; static DEF_TYPEID(reshape_op_s); static void reshape_forward(const linop_data_t* _data, complex float* dst, const complex float* src) { const struct reshape_op_s* data = CAST_DOWN(reshape_op_s, _data); md_copy(data->N, data->dims, dst, src, CFL_SIZE); } static void reshape_free(const linop_data_t* _data) { const struct reshape_op_s* data = CAST_DOWN(reshape_op_s, _data); xfree(data->dims); xfree(data); } struct linop_s* linop_reshape_create(unsigned int A, const long out_dims[A], int B, const long in_dims[B]) { PTR_ALLOC(struct reshape_op_s, data); SET_TYPEID(reshape_op_s, data); assert(md_calc_size(A, out_dims) == md_calc_size(B, in_dims)); unsigned int N = A; data->N = N; long* dims = *TYPE_ALLOC(long[N]); md_copy_dims(N, dims, out_dims); data->dims = dims; return linop_create(A, out_dims, B, in_dims, CAST_UP(PTR_PASS(data)), reshape_forward, reshape_forward, reshape_forward, NULL, reshape_free); } struct transpose_op_s { INTERFACE(linop_data_t); int N; int a; int b; const long* dims; }; static DEF_TYPEID(transpose_op_s); static void transpose_forward(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(transpose_op_s, _data); long odims[data->N]; md_copy_dims(data->N, odims, data->dims); odims[data->a] = data->dims[data->b]; odims[data->b] = data->dims[data->a]; md_transpose(data->N, data->a, data->b, odims, dst, data->dims, src, CFL_SIZE); } static void transpose_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(transpose_op_s, _data); md_copy(data->N, data->dims, dst, src, CFL_SIZE); } static void transpose_free(const linop_data_t* _data) { auto data = CAST_DOWN(transpose_op_s, _data); xfree(data->dims); xfree(data); } struct linop_s* linop_transpose_create(int N, int a, int b, const long dims[N]) { assert((0 <= a) && (a < N)); assert((0 <= b) && (b < N)); assert(a != b); PTR_ALLOC(struct transpose_op_s, data); SET_TYPEID(transpose_op_s, data); data->N = N; data->a = a; data->b = b; long* idims = *TYPE_ALLOC(long[N]); md_copy_dims(N, idims, dims); data->dims = idims; long odims[N]; md_copy_dims(N, odims, dims); odims[a] = idims[b]; odims[b] = idims[a]; return linop_create(N, odims, N, idims, CAST_UP(PTR_PASS(data)), transpose_forward, transpose_forward, transpose_normal, NULL, transpose_free); } struct operator_matrix_s { INTERFACE(linop_data_t); const complex float* mat; const complex float* mat_gram; // A^H A #ifdef USE_CUDA const complex float* mat_gpu; const complex float* mat_gram_gpu; #endif unsigned int N; const long* mat_dims; const long* out_dims; const long* in_dims; const long* grm_dims; const long* gin_dims; const long* gout_dims; }; static DEF_TYPEID(operator_matrix_s); static void linop_matrix_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(operator_matrix_s, _data); const complex float* mat = data->mat; #ifdef USE_CUDA if (cuda_ondevice(src)) { if (NULL == data->mat_gpu) data->mat_gpu = md_gpu_move(data->N, data->mat_dims, data->mat, CFL_SIZE); mat = data->mat_gpu; } #endif md_ztenmul(data->N, data->out_dims, dst, data->in_dims, src, data->mat_dims, mat); } static void linop_matrix_apply_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(operator_matrix_s, _data); const complex float* mat = data->mat; #ifdef USE_CUDA if (cuda_ondevice(src)) { if (NULL == data->mat_gpu) data->mat_gpu = md_gpu_move(data->N, data->mat_dims, data->mat, CFL_SIZE); mat = data->mat_gpu; } #endif md_ztenmulc(data->N, data->in_dims, dst, data->out_dims, src, data->mat_dims, mat); } static void linop_matrix_apply_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(operator_matrix_s, _data); if (NULL == data->mat_gram) { complex float* tmp = md_alloc_sameplace(data->N, data->out_dims, CFL_SIZE, src); linop_matrix_apply(_data, tmp, src); linop_matrix_apply_adjoint(_data, dst, tmp); md_free(tmp); } else { const complex float* mat_gram = data->mat_gram; #ifdef USE_CUDA if (cuda_ondevice(src)) { if (NULL == data->mat_gram_gpu) data->mat_gram_gpu = md_gpu_move(2 * data->N, data->grm_dims, data->mat_gram, CFL_SIZE); mat_gram = data->mat_gram_gpu; } #endif md_ztenmul(2 * data->N, data->gout_dims, dst, data->gin_dims, src, data->grm_dims, mat_gram); } } static void linop_matrix_del(const linop_data_t* _data) { auto data = CAST_DOWN(operator_matrix_s, _data); xfree(data->out_dims); xfree(data->mat_dims); xfree(data->in_dims); xfree(data->gin_dims); xfree(data->gout_dims); xfree(data->grm_dims); md_free(data->mat); md_free(data->mat_gram); #ifdef USE_CUDA md_free(data->mat_gpu); md_free(data->mat_gram_gpu); #endif xfree(data); } static void shadow_dims(unsigned int N, long out[2 * N], const long in[N]) { for (unsigned int i = 0; i < N; i++) { out[2 * i + 0] = in[i]; out[2 * i + 1] = 1; } } /* O I M G * 1 1 1 1 - not used * 1 1 A ! - forbidden * 1 A 1 ! - forbidden * A 1 1 ! - forbidden * A A 1 1 - replicated * A 1 A 1 - output * 1 A A A/A - input * A A A A - batch */ static struct operator_matrix_s* linop_matrix_priv2(unsigned int N, const long out_dims[N], const long in_dims[N], const long matrix_dims[N], const complex float* matrix) { // to get assertions and cost estimate long max_dims[N]; md_tenmul_dims(N, max_dims, out_dims, in_dims, matrix_dims); PTR_ALLOC(struct operator_matrix_s, data); SET_TYPEID(operator_matrix_s, data); data->N = N; PTR_ALLOC(long[N], out_dims1); md_copy_dims(N, *out_dims1, out_dims); data->out_dims = *PTR_PASS(out_dims1); PTR_ALLOC(long[N], mat_dims1); md_copy_dims(N, *mat_dims1, matrix_dims); data->mat_dims = *PTR_PASS(mat_dims1); PTR_ALLOC(long[N], in_dims1); md_copy_dims(N, *in_dims1, in_dims); data->in_dims = *PTR_PASS(in_dims1); complex float* mat = md_alloc(N, matrix_dims, CFL_SIZE); md_copy(N, matrix_dims, mat, matrix, CFL_SIZE); data->mat = mat; data->mat_gram = NULL; #ifdef USE_CUDA data->mat_gpu = NULL; data->mat_gram_gpu = NULL; #endif #if 1 // pre-multiply gram matrix (if there is a cost reduction) unsigned long out_flags = md_nontriv_dims(N, out_dims); unsigned long in_flags = md_nontriv_dims(N, in_dims); unsigned long del_flags = in_flags & ~out_flags; unsigned long new_flags = out_flags & ~in_flags; /* we double (again) for the gram matrix */ PTR_ALLOC(long[2 * N], mat_dims2); PTR_ALLOC(long[2 * N], in_dims2); PTR_ALLOC(long[2 * N], gmt_dims2); PTR_ALLOC(long[2 * N], gin_dims2); PTR_ALLOC(long[2 * N], grm_dims2); PTR_ALLOC(long[2 * N], gout_dims2); shadow_dims(N, *gmt_dims2, matrix_dims); shadow_dims(N, *mat_dims2, matrix_dims); shadow_dims(N, *in_dims2, in_dims); shadow_dims(N, *gout_dims2, in_dims); shadow_dims(N, *gin_dims2, in_dims); shadow_dims(N, *grm_dims2, matrix_dims); /* move removed input dims into shadow position * for the gram matrix can have an output there */ for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(del_flags, i)) { assert((*mat_dims2)[2 * i + 0] == (*in_dims2)[2 * i + 0]); (*mat_dims2)[2 * i + 1] = (*mat_dims2)[2 * i + 0]; (*mat_dims2)[2 * i + 0] = 1; (*in_dims2)[2 * i + 1] = (*gin_dims2)[2 * i + 0]; (*in_dims2)[2 * i + 0] = 1; } } for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(new_flags, i)) { (*grm_dims2)[2 * i + 0] = 1; (*grm_dims2)[2 * i + 1] = 1; } if (MD_IS_SET(del_flags, i)) { (*gout_dims2)[2 * i + 1] = (*gin_dims2)[2 * i + 0]; (*gout_dims2)[2 * i + 0] = 1; (*grm_dims2)[2 * i + 0] = in_dims[i]; (*grm_dims2)[2 * i + 1] = in_dims[i]; } } long gmx_dims[2 * N]; md_tenmul_dims(2 * N, gmx_dims, *gout_dims2, *gin_dims2, *grm_dims2); long mult_mat = md_calc_size(N, max_dims); long mult_gram = md_calc_size(2 * N, gmx_dims); if (mult_gram < 2 * mult_mat) { // FIXME: rethink debug_printf(DP_DEBUG2, "Gram matrix: 2x %ld vs %ld\n", mult_mat, mult_gram); complex float* mat_gram = md_alloc(2 * N, *grm_dims2, CFL_SIZE); md_ztenmulc(2 * N, *grm_dims2, mat_gram, *gmt_dims2, matrix, *mat_dims2, matrix); data->mat_gram = mat_gram; } PTR_FREE(gmt_dims2); PTR_FREE(mat_dims2); PTR_FREE(in_dims2); data->gin_dims = *PTR_PASS(gin_dims2); data->gout_dims = *PTR_PASS(gout_dims2); data->grm_dims = *PTR_PASS(grm_dims2); #else data->gin_dims = NULL; data->gout_dims = NULL; data->grm_dims = NULL; #endif return PTR_PASS(data); } static struct operator_matrix_s* linop_matrix_priv(unsigned int N, const long out_dims[N], const long in_dims[N], const long matrix_dims[N], const complex float* matrix) { unsigned long out_flags = md_nontriv_dims(N, out_dims); unsigned long in_flags = md_nontriv_dims(N, in_dims); unsigned long del_flags = in_flags & ~out_flags; /* we double dimensions for chaining which can lead to * matrices with the same input and output dimension */ long out_dims2[2 * N]; long mat_dims2[2 * N]; long in_dims2[2 * N]; shadow_dims(N, out_dims2, out_dims); shadow_dims(N, mat_dims2, matrix_dims); shadow_dims(N, in_dims2, in_dims); /* move removed input dims into shadow position * which makes chaining easier below */ for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(del_flags, i)) { assert(1 == out_dims2[2 * i + 0]); assert(mat_dims2[2 * i + 0] == in_dims2[2 * i + 0]); mat_dims2[2 * i + 1] = mat_dims2[2 * i + 0]; mat_dims2[2 * i + 0] = 1; in_dims2[2 * i + 1] = in_dims[i]; in_dims2[2 * i + 0] = 1; } } return linop_matrix_priv2(2 * N, out_dims2, in_dims2, mat_dims2, matrix); } /** * Operator interface for a true matrix: * out = mat * in * in: [x x x x 1 x x K x x] * mat: [x x x x T x x K x x] * out: [x x x x T x x 1 x x] * where the x's are arbitrary dimensions and T and K may be transposed * * @param N number of dimensions * @param out_dims output dimensions after applying the matrix (codomain) * @param in_dims input dimensions to apply the matrix (domain) * @param matrix_dims dimensions of the matrix * @param matrix matrix data */ struct linop_s* linop_matrix_create(unsigned int N, const long out_dims[N], const long in_dims[N], const long matrix_dims[N], const complex float* matrix) { struct operator_matrix_s* data = linop_matrix_priv(N, out_dims, in_dims, matrix_dims, matrix); return linop_create(N, out_dims, N, in_dims, CAST_UP(data), linop_matrix_apply, linop_matrix_apply_adjoint, linop_matrix_apply_normal, NULL, linop_matrix_del); } /** * Efficiently chain two matrix linops by multiplying the actual matrices together. * Stores a copy of the new matrix. * Returns: C = B A * * @param a first matrix (applied to input) * @param b second matrix (applied to output of first matrix) */ struct linop_s* linop_matrix_chain(const struct linop_s* a, const struct linop_s* b) { const auto a_data = CAST_DOWN(operator_matrix_s, linop_get_data(a)); const auto b_data = CAST_DOWN(operator_matrix_s, linop_get_data(b)); // check compatibility assert(linop_codomain(a)->N == linop_domain(b)->N); assert(md_check_compat(linop_codomain(a)->N, 0u, linop_codomain(a)->dims, linop_domain(b)->dims)); unsigned int D = linop_domain(a)->N; unsigned long outB_flags = md_nontriv_dims(D, linop_codomain(b)->dims); unsigned long inB_flags = md_nontriv_dims(D, linop_domain(b)->dims); unsigned long delB_flags = inB_flags & ~outB_flags; unsigned int N = a_data->N; assert(N == 2 * D); long in_dims[N]; md_copy_dims(N, in_dims, a_data->in_dims); long matA_dims[N]; md_copy_dims(N, matA_dims, a_data->mat_dims); long matB_dims[N]; md_copy_dims(N, matB_dims, b_data->mat_dims); long out_dims[N]; md_copy_dims(N, out_dims, b_data->out_dims); for (unsigned int i = 0; i < D; i++) { if (MD_IS_SET(delB_flags, i)) { matA_dims[2 * i + 0] = a_data->mat_dims[2 * i + 1]; matA_dims[2 * i + 1] = a_data->mat_dims[2 * i + 0]; in_dims[2 * i + 0] = a_data->in_dims[2 * i + 1]; in_dims[2 * i + 1] = a_data->in_dims[2 * i + 0]; } } long matrix_dims[N]; md_singleton_dims(N, matrix_dims); unsigned long iflags = md_nontriv_dims(N, in_dims); unsigned long oflags = md_nontriv_dims(N, out_dims); unsigned long flags = iflags | oflags; // we combine a and b and sum over dims not in input or output md_max_dims(N, flags, matrix_dims, matA_dims, matB_dims); debug_printf(DP_DEBUG1, "tensor chain: %ld x %ld -> %ld\n", md_calc_size(N, matA_dims), md_calc_size(N, matB_dims), md_calc_size(N, matrix_dims)); complex float* matrix = md_alloc(N, matrix_dims, CFL_SIZE); debug_print_dims(DP_DEBUG2, N, matrix_dims); debug_print_dims(DP_DEBUG2, N, in_dims); debug_print_dims(DP_DEBUG2, N, matA_dims); debug_print_dims(DP_DEBUG2, N, matB_dims); debug_print_dims(DP_DEBUG2, N, out_dims); md_ztenmul(N, matrix_dims, matrix, matA_dims, a_data->mat, matB_dims, b_data->mat); // priv2 takes our doubled dimensions struct operator_matrix_s* data = linop_matrix_priv2(N, out_dims, in_dims, matrix_dims, matrix); /* although we internally use different dimensions we define the * correct interface */ struct linop_s* c = linop_create(linop_codomain(b)->N, linop_codomain(b)->dims, linop_domain(a)->N, linop_domain(a)->dims, CAST_UP(data), linop_matrix_apply, linop_matrix_apply_adjoint, linop_matrix_apply_normal, NULL, linop_matrix_del); md_free(matrix); return c; } struct fft_linop_s { INTERFACE(linop_data_t); const struct operator_s* frw; const struct operator_s* adj; bool center; float nscale; int N; long* dims; long* strs; }; static DEF_TYPEID(fft_linop_s); static void fft_linop_apply(const linop_data_t* _data, complex float* out, const complex float* in) { const auto data = CAST_DOWN(fft_linop_s, _data); if (in != out) md_copy2(data->N, data->dims, data->strs, out, data->strs, in, CFL_SIZE); operator_apply(data->frw, data->N, data->dims, out, data->N, data->dims, out); } static void fft_linop_adjoint(const linop_data_t* _data, complex float* out, const complex float* in) { const auto data = CAST_DOWN(fft_linop_s, _data); if (in != out) md_copy2(data->N, data->dims, data->strs, out, data->strs, in, CFL_SIZE); operator_apply(data->adj, data->N, data->dims, out, data->N, data->dims, out); } static void fft_linop_free(const linop_data_t* _data) { const auto data = CAST_DOWN(fft_linop_s, _data); fft_free(data->frw); fft_free(data->adj); xfree(data->dims); xfree(data->strs); xfree(data); } static void fft_linop_normal(const linop_data_t* _data, complex float* out, const complex float* in) { const auto data = CAST_DOWN(fft_linop_s, _data); if (data->center) md_copy(data->N, data->dims, out, in, CFL_SIZE); else md_zsmul(data->N, data->dims, out, in, data->nscale); } static struct linop_s* linop_fft_create_priv(int N, const long dims[N], unsigned int flags, bool forward, bool center, bool measure) { const struct operator_s* plan = NULL; const struct operator_s* iplan = NULL; if (measure) { plan = fft_measure_create(N, dims, flags, true, false); iplan = fft_measure_create(N, dims, flags, true, true); } else { complex float* tmp1 = md_alloc(N, dims, CFL_SIZE); plan = fft_create(N, dims, flags, tmp1, tmp1, false); iplan = fft_create(N, dims, flags, tmp1, tmp1, true); md_free(tmp1); } PTR_ALLOC(struct fft_linop_s, data); SET_TYPEID(fft_linop_s, data); data->frw = plan; data->adj = iplan; data->N = N; data->center = center; data->dims = *TYPE_ALLOC(long[N]); md_copy_dims(N, data->dims, dims); data->strs = *TYPE_ALLOC(long[N]); md_calc_strides(N, data->strs, data->dims, CFL_SIZE); long fft_dims[N]; md_select_dims(N, flags, fft_dims, dims); data->nscale = (float)md_calc_size(N, fft_dims); lop_fun_t apply = forward ? fft_linop_apply : fft_linop_adjoint; lop_fun_t adjoint = forward ? fft_linop_adjoint : fft_linop_apply; struct linop_s* lop = linop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), apply, adjoint, fft_linop_normal, NULL, fft_linop_free); if (center) { // FIXME: should only allocate flagged dims complex float* fftmod_mat = md_alloc(N, dims, CFL_SIZE); complex float* fftmodk_mat = md_alloc(N, dims, CFL_SIZE); // we need fftmodk only because we want to apply scaling only once complex float one[1] = { 1. }; md_fill(N, dims, fftmod_mat, one, CFL_SIZE); fftmod(N, dims, flags, fftmodk_mat, fftmod_mat); fftscale(N, dims, flags, fftmod_mat, fftmodk_mat); struct linop_s* mod = linop_cdiag_create(N, dims, ~0u, fftmod_mat); struct linop_s* modk = linop_cdiag_create(N, dims, ~0u, fftmodk_mat); struct linop_s* tmp = linop_chain(mod, lop); linop_free(lop); linop_free(mod); lop = linop_chain(tmp, modk); linop_free(tmp); linop_free(modk); md_free(fftmod_mat); md_free(fftmodk_mat); } return lop; } /** * Uncentered forward Fourier transform linear operator * * @param N number of dimensions * @param dims dimensions of input * @param flags bitmask of the dimensions to apply the Fourier transform * @param gpu use gpu */ struct linop_s* linop_fft_create(int N, const long dims[N], unsigned int flags) { return linop_fft_create_priv(N, dims, flags, true, false, true); } /** * Uncentered inverse Fourier transform linear operator * * @param N number of dimensions * @param dims dimensions of input * @param flags bitmask of the dimensions to apply the Fourier transform */ struct linop_s* linop_ifft_create(int N, const long dims[N], unsigned int flags) { return linop_fft_create_priv(N, dims, flags, false, false, true); } /** * Centered forward Fourier transform linear operator * * @param N number of dimensions * @param dims dimensions of input * @param flags bitmask of the dimensions to apply the Fourier transform */ struct linop_s* linop_fftc_create(int N, const long dims[N], unsigned int flags) { return linop_fft_create_priv(N, dims, flags, true, true, true); } /** * Centered inverse Fourier transform linear operator * * @param N number of dimensions * @param dims dimensions of input * @param flags bitmask of the dimensions to apply the Fourier transform */ struct linop_s* linop_ifftc_create(int N, const long dims[N], unsigned int flags) { return linop_fft_create_priv(N, dims, flags, false, true, true); } /** * Uncentered forward Fourier transform linear operator * no fft_measure_create used * * @param N number of dimensions * @param dims dimensions of input * @param flags bitmask of the dimensions to apply the Fourier transform * @param gpu use gpu */ struct linop_s* linop_fft_create_no_measure(int N, const long dims[N], unsigned int flags) { return linop_fft_create_priv(N, dims, flags, true, false, false); } struct linop_cdf97_s { INTERFACE(linop_data_t); unsigned int N; const long* dims; unsigned int flags; }; static DEF_TYPEID(linop_cdf97_s); static void linop_cdf97_apply(const linop_data_t* _data, complex float* out, const complex float* in) { const auto data = CAST_DOWN(linop_cdf97_s, _data); md_copy(data->N, data->dims, out, in, CFL_SIZE); md_cdf97z(data->N, data->dims, data->flags, out); } static void linop_cdf97_adjoint(const linop_data_t* _data, complex float* out, const complex float* in) { const auto data = CAST_DOWN(linop_cdf97_s, _data); md_copy(data->N, data->dims, out, in, CFL_SIZE); md_icdf97z(data->N, data->dims, data->flags, out); } static void linop_cdf97_normal(const linop_data_t* _data, complex float* out, const complex float* in) { const auto data = CAST_DOWN(linop_cdf97_s, _data); md_copy(data->N, data->dims, out, in, CFL_SIZE); } static void linop_cdf97_free(const linop_data_t* _data) { const auto data = CAST_DOWN(linop_cdf97_s, _data); xfree(data->dims); xfree(data); } /** * Wavelet CFD9/7 transform operator * * @param N number of dimensions * @param dims dimensions of input * @param flags bitmask of the dimensions to apply the Fourier transform */ struct linop_s* linop_cdf97_create(int N, const long dims[N], unsigned int flags) { PTR_ALLOC(struct linop_cdf97_s, data); SET_TYPEID(linop_cdf97_s, data); PTR_ALLOC(long[N], ndims); md_copy_dims(N, *ndims, dims); data->N = N; data->dims = *ndims; data->flags = flags; return linop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), linop_cdf97_apply, linop_cdf97_adjoint, linop_cdf97_normal, NULL, linop_cdf97_free); } struct conv_data_s { INTERFACE(linop_data_t); struct conv_plan* plan; }; static DEF_TYPEID(conv_data_s); static void linop_conv_forward(const linop_data_t* _data, complex float* out, const complex float* in) { auto data = CAST_DOWN(conv_data_s, _data); conv_exec(data->plan, out, in); } static void linop_conv_adjoint(const linop_data_t* _data, complex float* out, const complex float* in) { auto data = CAST_DOWN(conv_data_s, _data); conv_adjoint(data->plan, out, in); } static void linop_conv_free(const linop_data_t* _data) { auto data = CAST_DOWN(conv_data_s, _data); conv_free(data->plan); xfree(data); } /** * Convolution operator * * @param N number of dimensions * @param flags bitmask of the dimensions to apply convolution * @param ctype * @param cmode * @param odims output dimensions * @param idims input dimensions * @param kdims kernel dimensions * @param krn convolution kernel */ struct linop_s* linop_conv_create(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[N], const long idims[N], const long kdims[N], const complex float* krn) { PTR_ALLOC(struct conv_data_s, data); SET_TYPEID(conv_data_s, data); data->plan = conv_plan(N, flags, ctype, cmode, odims, idims, kdims, krn); return linop_create(N, odims, N, idims, CAST_UP(PTR_PASS(data)), linop_conv_forward, linop_conv_adjoint, NULL, NULL, linop_conv_free); } bart-0.5.00/src/linops/someops.h000066400000000000000000000055651353046746100165010ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __SOMEOPS_H #define __SOMEOPS_H #include #include "misc/cppwrap.h" extern struct linop_s* linop_cdiag_create(unsigned int N, const long dims[__VLA(N)], unsigned int flags, const _Complex float* diag); extern struct linop_s* linop_rdiag_create(unsigned int N, const long dims[__VLA(N)], unsigned int flags, const _Complex float* diag); extern struct linop_s* linop_identity_create(unsigned int N, const long dims[__VLA(N)]); extern struct linop_s* linop_resize_create(unsigned int N, const long out_dims[__VLA(N)], const long in_dims[__VLA(N)]); // deprecated extern struct linop_s* linop_resize_center_create(unsigned int N, const long out_dims[__VLA(N)], const long in_dims[__VLA(N)]); extern struct linop_s* linop_expand_create(unsigned int N, const long out_dims[__VLA(N)], const long in_dims[__VLA(N)]); extern struct linop_s* linop_reshape_create(unsigned int A, const long out_dims[__VLA(A)], int B, const long in_dims[__VLA(B)]); extern struct linop_s* linop_extract_create(unsigned int N, const long pos[N], const long out_dims[N], const long in_dims[N]); extern struct linop_s* linop_transpose_create(int N, int a, int b, const long dims[N]); extern struct linop_s* linop_fft_create(int N, const long dims[__VLA(N)], unsigned int flags); extern struct linop_s* linop_ifft_create(int N, const long dims[__VLA(N)], unsigned int flags); extern struct linop_s* linop_fftc_create(int N, const long dims[__VLA(N)], unsigned int flags); extern struct linop_s* linop_ifftc_create(int N, const long dims[__VLA(N)], unsigned int flags); extern struct linop_s* linop_fft_create_no_measure(int N, const long dims[__VLA(N)], unsigned int flags); extern struct linop_s* linop_cdf97_create(int N, const long dims[__VLA(N)], unsigned int flag); #ifndef __CONV_ENUMS #define __CONV_ENUMS enum conv_mode { CONV_SYMMETRIC, CONV_CAUSAL, CONV_ANTICAUSAL }; enum conv_type { CONV_CYCLIC, CONV_TRUNCATED, CONV_VALID, CONV_EXTENDED }; #endif extern struct linop_s* linop_conv_create(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[__VLA(N)], const long idims1[__VLA(N)], const long idims2[__VLA(N)], const _Complex float* src2); extern struct linop_s* linop_matrix_create(unsigned int N, const long out_dims[__VLA(N)], const long in_dims[__VLA(N)], const long matrix_dims[__VLA(N)], const _Complex float* matrix); extern struct linop_s* linop_matrix_altcreate(unsigned int N, const long out_dims[__VLA(N)], const long in_dims[__VLA(N)], const unsigned int T_dim, const unsigned int K_dim, const _Complex float* matrix); extern struct linop_s* linop_matrix_chain(const struct linop_s* a, const struct linop_s* b); #include "misc/cppwrap.h" #endif // __SOMEOPS_H bart-0.5.00/src/linops/sum.c000066400000000000000000000076761353046746100156200ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong * 2016-2019 Martin Uecker * */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "linops/linop.h" #include "misc/misc.h" #include "misc/mri.h" #include "sum.h" struct sum_data { INTERFACE(linop_data_t); long imgd_dims[DIMS]; long img_dims[DIMS]; long levels; long imgd_strs[DIMS]; long img_strs[DIMS]; }; static DEF_TYPEID(sum_data); static struct sum_data* sum_create_data(const long imgd_dims[DIMS]); static void sum_free_data(const linop_data_t* _data); static void sum_apply(const linop_data_t* _data, complex float* _dst, const complex float* _src); static void sum_apply_adjoint(const linop_data_t* _data, complex float* _dst, const complex float* _src); static void sum_apply_normal(const linop_data_t* _data, complex float* _dst, const complex float* _src); static void sum_apply_pinverse(const linop_data_t* _data, float lambda, complex float* _dst, const complex float* _src); const struct linop_s* linop_sum_create(const long imgd_dims[DIMS]) { struct sum_data* data = sum_create_data(imgd_dims); return linop_create(DIMS, data->img_dims, DIMS, data->imgd_dims, CAST_UP(data), sum_apply, sum_apply_adjoint, sum_apply_normal, sum_apply_pinverse, sum_free_data); } static struct sum_data* sum_create_data(const long imgd_dims[DIMS]) { PTR_ALLOC(struct sum_data, data); SET_TYPEID(sum_data, data); // decom dimensions md_copy_dims(DIMS, data->imgd_dims, imgd_dims); md_calc_strides(DIMS, data->imgd_strs, imgd_dims, CFL_SIZE); // image dimensions data->levels = imgd_dims[LEVEL_DIM]; md_select_dims(DIMS, ~LEVEL_FLAG, data->img_dims, imgd_dims); md_calc_strides(DIMS, data->img_strs, data->img_dims, CFL_SIZE); return PTR_PASS(data); } void sum_free_data(const linop_data_t* _data) { auto data = CAST_DOWN(sum_data, _data); xfree(data); } void sum_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(sum_data, _data); md_clear(DIMS, data->img_dims, dst, CFL_SIZE); md_zaxpy2(DIMS, data->imgd_dims, data->img_strs, dst, 1. / sqrtf(data->levels), data->imgd_strs, src); } void sum_apply_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(sum_data, _data); md_clear(DIMS, data->imgd_dims, dst, CFL_SIZE); md_zaxpy2(DIMS, data->imgd_dims, data->imgd_strs, dst, 1. / sqrtf(data->levels), data->img_strs, src); } void sum_apply_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(sum_data, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->img_dims, CFL_SIZE, dst); sum_apply(_data, tmp, src); sum_apply_adjoint(_data, dst, tmp); md_free(tmp); } /** * * x = (ATA + uI)^-1 b * */ void sum_apply_pinverse(const linop_data_t* _data, float rho, complex float* dst, const complex float* src) { auto data = CAST_DOWN(sum_data, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->img_dims, CFL_SIZE, dst); // get average md_clear(DIMS, data->img_dims, tmp, CFL_SIZE); md_zadd2(DIMS, data->imgd_dims, data->img_strs, tmp, data->img_strs, tmp , data->imgd_strs, src); md_zsmul(DIMS, data->img_dims, tmp, tmp, 1. / data->levels); // get non-average md_zsub2(DIMS, data->imgd_dims, data->imgd_strs, dst, data->imgd_strs, src, data->img_strs, tmp); // avg = avg / (1 + rho) md_zsmul(DIMS, data->img_dims, tmp, tmp, 1. / (1. + rho)); // nonavg = nonavg / rho md_zsmul(DIMS, data->imgd_dims, dst, dst, 1. / rho); // dst = avg + nonavg md_zadd2(DIMS, data->imgd_dims, data->imgd_strs, dst, data->imgd_strs, dst, data->img_strs, tmp); md_free(tmp); } bart-0.5.00/src/linops/sum.h000066400000000000000000000002771353046746100156130ustar00rootroot00000000000000 #ifdef __cplusplus extern "C" { #endif #include "misc/mri.h" struct operator_s; extern const struct linop_s* linop_sum_create(const long imgd_dims[DIMS]); #ifdef __cplusplus } #endif bart-0.5.00/src/linops/waveop.c000066400000000000000000000064471353046746100163100ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2017 Martin Uecker * 2017 Sofia Dimoudi */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "linops/linop.h" #include "misc/misc.h" #include "wavelet/wavelet.h" #include "waveop.h" struct wavelet_s { INTERFACE(linop_data_t); unsigned int N; unsigned int flags; const long* idims; const long* istr; const long* odims; const long* ostr; const long* minsize; long* shifts; bool randshift; int rand_state; }; static DEF_TYPEID(wavelet_s); static int wrand_lim(unsigned int* state, int limit) { int divisor = RAND_MAX / (limit + 1); int retval; do { retval = rand_r(state) / divisor; } while (retval > limit); return retval; } static void wavelet_forward(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(wavelet_s, _data); if (data->randshift) { for (unsigned int i = 0; i < data->N; i++) { if (MD_IS_SET(data->flags, i)) { int levels = wavelet_num_levels(data->N, MD_BIT(i), data->idims, data->minsize, 4); data->shifts[i] = wrand_lim((unsigned int*)&data->rand_state, 1 << levels); assert(data->shifts[i] < data->idims[i]); } } } fwt2(data->N, data->flags, data->shifts, data->odims, data->ostr, dst, data->idims, data->istr, src, data->minsize, 4, wavelet_dau2); } static void wavelet_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(wavelet_s, _data); iwt2(data->N, data->flags, data->shifts, data->idims, data->istr, dst, data->odims, data->ostr, src, data->minsize, 4, wavelet_dau2); } static void wavelet_del(const linop_data_t* _data) { const auto data = CAST_DOWN(wavelet_s, _data); xfree(data->odims); xfree(data->ostr); xfree(data->idims); xfree(data->istr); xfree(data->minsize); xfree(data->shifts); xfree(data); } struct linop_s* linop_wavelet_create(unsigned int N, unsigned int flags, const long dims[N], const long istr[N], const long minsize[N], bool randshift) { PTR_ALLOC(struct wavelet_s, data); SET_TYPEID(wavelet_s, data); data->N = N; data->flags = flags; data->randshift = randshift; data->rand_state = 1; long (*idims)[N] = TYPE_ALLOC(long[N]); md_copy_dims(N, *idims, dims); data->idims = *idims; long (*nistr)[N] = TYPE_ALLOC(long[N]); md_copy_strides(N, *nistr, istr); data->istr = *nistr; long (*nminsize)[N] = TYPE_ALLOC(long[N]); md_copy_dims(N, *nminsize, minsize); data->minsize = *nminsize; long (*odims)[N] = TYPE_ALLOC(long[N]); wavelet_coeffs2(N, flags, *odims, dims, minsize, 4); data->odims = *odims; long (*ostr)[N] = TYPE_ALLOC(long[N]); md_calc_strides(N, *ostr, *odims, CFL_SIZE); data->ostr = *ostr; long (*shifts)[N] = TYPE_ALLOC(long[N]); for (unsigned int i = 0; i < data->N; i++) (*shifts)[i] = 0; data->shifts = *shifts; return linop_create2(N, *odims, *ostr, N, dims, istr, CAST_UP(PTR_PASS(data)), wavelet_forward, wavelet_adjoint, NULL, NULL, wavelet_del); } bart-0.5.00/src/linops/waveop.h000066400000000000000000000006601353046746100163040ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" extern struct linop_s* linop_wavelet_create(unsigned int N, unsigned int flags, const long dims[__VLA(N)], const long istr[__VLA(N)], const long minsize[__VLA(N)], _Bool randshift); #include "misc/cppwrap.h" bart-0.5.00/src/looklocker.c000066400000000000000000000040331353046746100156340ustar00rootroot00000000000000/* Copyright 2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2019 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "misc/mri.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Compute T1 map from M_0, M_ss, and R_1*.\n"; int main_looklocker(int argc, char* argv[argc]) { float threshold = 0.2; float scaling_M0 = 2.0; float Td = 0.; const struct opt_s opts[] = { OPT_FLOAT('t', &threshold, "threshold", "Pixels with M0 values smaller than {threshold} are set to zero."), OPT_FLOAT('D', &Td, "delay", "Time between the middle of inversion pulse and the first excitation."), }; cmdline(&argc, argv, 2, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long idims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, idims); long odims[DIMS]; md_select_dims(DIMS, ~COEFF_FLAG, odims, idims); complex float* out_data = create_cfl(argv[2], DIMS, odims); long istrs[DIMS]; md_calc_strides(DIMS, istrs, idims, CFL_SIZE); long ostrs[DIMS]; md_calc_strides(DIMS, ostrs, odims, CFL_SIZE); long pos[DIMS] = { 0 }; do { complex float Ms = MD_ACCESS(DIMS, istrs, (pos[COEFF_DIM] = 0, pos), in_data); complex float M0 = MD_ACCESS(DIMS, istrs, (pos[COEFF_DIM] = 1, pos), in_data); complex float R1s = MD_ACCESS(DIMS, istrs, (pos[COEFF_DIM] = 2, pos), in_data); float T1 = scaling_M0 * cabs(M0) / (cabs(Ms) * cabs(R1s)) + 2. * Td; if (safe_isnanf(T1) || (cabs(Ms) < threshold)) T1 = 0.; MD_ACCESS(DIMS, ostrs, (pos[COEFF_DIM] = 0, pos), out_data) = T1; } while(md_next(DIMS, odims, ~COEFF_FLAG, pos)); unmap_cfl(DIMS, idims, in_data); unmap_cfl(DIMS, odims, out_data); return 0; } bart-0.5.00/src/lowrank/000077500000000000000000000000001353046746100150015ustar00rootroot00000000000000bart-0.5.00/src/lowrank/batchsvd.c000066400000000000000000000036721353046746100167530ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Frank Ong * 2016 Martin Uecker */ #include #include "misc/misc.h" #include "num/blas.h" #include "num/lapack.h" #include "num/linalg.h" #include "batchsvd.h" void batch_svthresh(long M, long N, long num_blocks, float lambda, complex float dst[num_blocks][N][M]) { #pragma omp parallel { long minMN = MIN(M, N); PTR_ALLOC(complex float[minMN][M], U); PTR_ALLOC(complex float[N][minMN], VT); PTR_ALLOC(float[minMN], S); PTR_ALLOC(complex float[minMN][minMN], AA); #pragma omp for for (int b = 0; b < num_blocks; b++) { // Compute upper bound | A^T A |_inf // FIXME: this is based on gratuitous guess-work about the obscure // API of this FORTRAN from ancient times... Is it really worth it? blas_csyrk('U', (N <= M) ? 'T' : 'N', (N <= M) ? N : M, (N <= M) ? M : N, 1., M, dst[b], 0., minMN, *AA); // lambda_max( A ) <= max_i sum_j | a_i^T a_j | float s_upperbound = 0; for (int i = 0; i < minMN; i++) { float s = 0; for (int j = 0; j < minMN; j++) s += cabsf((*AA)[MAX(i, j)][MIN(i, j)]); s_upperbound = MAX(s_upperbound, s); } /* avoid doing SVD-based thresholding if we know from * the upper bound that lambda_max <= lambda and the * result must be zero */ if (s_upperbound < lambda * lambda) { mat_zero(N, M, dst[b]); continue; } lapack_svd_econ(M, N, *U, *VT, *S, dst[b]); // soft threshold for (int i = 0; i < minMN; i++) for (int j = 0; j < N; j++) (*VT)[j][i] *= ((*S)[i] < lambda) ? 0. : ((*S)[i] - lambda); blas_matrix_multiply(M, N, minMN, dst[b], *U, *VT); } PTR_FREE(U); PTR_FREE(VT); PTR_FREE(S); PTR_FREE(AA); } // #pragma omp parallel } bart-0.5.00/src/lowrank/batchsvd.h000066400000000000000000000002111353046746100167420ustar00rootroot00000000000000 #include extern void batch_svthresh(long M, long N, long num_blocks, float lambda, complex float dst[num_blocks][N][M]); bart-0.5.00/src/lowrank/lrthresh.c000066400000000000000000000257061353046746100170120ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015. Tao Zhang and Joseph Cheng. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2015 Frank Ong * 2014 Tao Zhang * 2014 Joseph Cheng * 2014 Jon Tamir * 2014-2018 Martin Uecker */ #include #include #include #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/linalg.h" #include "num/ops.h" #include "num/ops_p.h" #include "num/blockproc.h" #include "num/casorati.h" #include "iter/thresh.h" #include "lowrank/batchsvd.h" #include "lowrank/svthresh.h" #include "lrthresh.h" struct lrthresh_data_s { INTERFACE(operator_data_t); float lambda; bool randshift; bool noise; int remove_mean; long strs_lev[DIMS]; long strs[DIMS]; long dims_decom[DIMS]; long dims[DIMS]; unsigned long mflags; unsigned long flags; long levels; long blkdims[MAX_LEV][DIMS]; bool overlapping_blocks; }; static DEF_TYPEID(lrthresh_data_s); static struct lrthresh_data_s* lrthresh_create_data(const long dims_decom[DIMS], bool randshift, unsigned long mflags, const long blkdims[MAX_LEV][DIMS], float lambda, bool noise, int remove_mean, bool overlapping_blocks); static void lrthresh_free_data(const operator_data_t* data); static void lrthresh_apply(const operator_data_t* _data, float lambda, complex float* dst, const complex float* src); /** * Intialize lrthresh operator * * @param dims_decom - decomposition dimensions * @param randshift - randshift boolean * @param mflags - selects which dimensions gets reshaped as the first dimension in matrix * @param blkdims - contains block dimensions for all levels * */ const struct operator_p_s* lrthresh_create(const long dims_lev[DIMS], bool randshift, unsigned long mflags, const long blkdims[MAX_LEV][DIMS], float lambda, bool noise, int remove_mean, bool overlapping_blocks) { struct lrthresh_data_s* data = lrthresh_create_data(dims_lev, randshift, mflags, blkdims, lambda, noise, remove_mean, overlapping_blocks); return operator_p_create(DIMS, dims_lev, DIMS, dims_lev, CAST_UP(data), lrthresh_apply, lrthresh_free_data); } /** * Intialize lrthresh data * * @param dims_decom - dimensions with levels at LEVEL_DIMS * @param randshift - randshift boolean * @param mflags - selects which dimensions gets reshaped as the first dimension in matrix * @param blkdims - contains block dimensions for all levels * */ static struct lrthresh_data_s* lrthresh_create_data(const long dims_decom[DIMS], bool randshift, unsigned long mflags, const long blkdims[MAX_LEV][DIMS], float lambda, bool noise, int remove_mean, bool overlapping_blocks) { PTR_ALLOC(struct lrthresh_data_s, data); SET_TYPEID(lrthresh_data_s, data); data->randshift = randshift; data->mflags = mflags; data->lambda = lambda; data->noise = noise; data->remove_mean = remove_mean; data->overlapping_blocks = overlapping_blocks; // level dimensions md_copy_dims(DIMS, data->dims_decom, dims_decom); md_calc_strides(DIMS, data->strs_lev, dims_decom, CFL_SIZE); // image dimensions data->levels = dims_decom[LEVEL_DIM]; md_select_dims(DIMS, ~LEVEL_FLAG, data->dims, dims_decom); md_calc_strides(DIMS, data->strs, data->dims, CFL_SIZE); // blkdims for(long l = 0; l < data->levels; l++) { for (long i = 0; i < DIMS; i++) data->blkdims[l][i] = blkdims[l][i]; } return PTR_PASS(data); } /** * Free lrthresh operator */ static void lrthresh_free_data(const operator_data_t* _data) { xfree(CAST_DOWN(lrthresh_data_s, _data)); } /* * Return a random number between 0 and limit inclusive. */ static int rand_lim(int limit) { int divisor = RAND_MAX / (limit + 1); int retval; do { retval = rand() / divisor; } while (retval > limit); return retval; } /* * Low rank threhsolding for arbitrary block sizes */ static void lrthresh_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { auto data = CAST_DOWN(lrthresh_data_s, _data); float lambda = mu * data->lambda; long strs1[DIMS]; md_calc_strides(DIMS, strs1, data->dims_decom, 1); //#pragma omp parallel for for (int l = 0; l < data->levels; l++) { complex float* dstl = dst + l * strs1[LEVEL_DIM]; const complex float* srcl = src + l * strs1[LEVEL_DIM]; long blkdims[DIMS]; long shifts[DIMS]; long unshifts[DIMS]; long zpad_dims[DIMS]; long M = 1; for (unsigned int i = 0; i < DIMS; i++) { blkdims[i] = data->blkdims[l][i]; zpad_dims[i] = (data->dims[i] + blkdims[i] - 1) / blkdims[i]; zpad_dims[i] *= blkdims[i]; if (MD_IS_SET(data->mflags, i)) M *= blkdims[i]; if (data->randshift) shifts[i] = rand_lim(MIN(blkdims[i] - 1, zpad_dims[i] - blkdims[i])); else shifts[i] = 0; unshifts[i] = -shifts[i]; } long zpad_strs[DIMS]; md_calc_strides(DIMS, zpad_strs, zpad_dims, CFL_SIZE); long blk_size = md_calc_size(DIMS, blkdims); long img_size = md_calc_size(DIMS, zpad_dims); long N = blk_size / M; long B = img_size / blk_size; if (data->noise && (l == data->levels - 1)) { M = img_size; N = 1; B = 1; } complex float* tmp = md_alloc_sameplace(DIMS, zpad_dims, CFL_SIZE, dst); md_circ_ext(DIMS, zpad_dims, tmp, data->dims, srcl, CFL_SIZE); md_circ_shift(DIMS, zpad_dims, shifts, tmp, tmp, CFL_SIZE); long mat_dims[2]; (data->overlapping_blocks ? casorati_dims : basorati_dims)(DIMS, mat_dims, blkdims, zpad_dims); complex float* tmp_mat = md_alloc_sameplace(2, mat_dims, CFL_SIZE, dst); complex float* tmp_mat2 = tmp_mat; // Reshape image into a blk_size x number of blocks matrix (data->overlapping_blocks ? casorati_matrix : basorati_matrix)(DIMS, blkdims, mat_dims, tmp_mat, zpad_dims, zpad_strs, tmp); long num_blocks = mat_dims[1]; long mat2_dims[2] = { mat_dims[0], mat_dims[1] }; // FIXME: casorati and basorati are transposes of each other if (data->overlapping_blocks) { mat2_dims[0] = mat_dims[1]; mat2_dims[1] = mat_dims[0]; tmp_mat2 = md_alloc_sameplace(2, mat2_dims, CFL_SIZE, dst); md_transpose(2, 0, 1, mat2_dims, tmp_mat2, mat_dims, tmp_mat, CFL_SIZE); num_blocks = mat2_dims[1]; if (B > 1) B = mat2_dims[1]; } debug_printf(DP_DEBUG4, "M=%d, N=%d, B=%d, num_blocks=%d, img_size=%d, blk_size=%d\n", M, N, B, num_blocks, img_size, blk_size); batch_svthresh(M, N, num_blocks, lambda * GWIDTH(M, N, B), *(complex float (*)[mat2_dims[1]][M][N])tmp_mat2); // for ( int b = 0; b < mat_dims[1]; b++ ) // svthresh(M, N, lambda * GWIDTH(M, N, B), tmp_mat, tmp_mat); if (data->overlapping_blocks) { md_transpose(2, 0, 1, mat_dims, tmp_mat, mat2_dims, tmp_mat2, CFL_SIZE); } (data->overlapping_blocks ? casorati_matrixH : basorati_matrixH)(DIMS, blkdims, zpad_dims, zpad_strs, tmp, mat_dims, tmp_mat); if (data->overlapping_blocks) { md_zsmul(DIMS, zpad_dims, tmp, tmp, 1. / M); md_free(tmp_mat2); } md_circ_shift(DIMS, zpad_dims, unshifts, tmp, tmp, CFL_SIZE); md_resize(DIMS, data->dims, dstl, zpad_dims, tmp, CFL_SIZE); md_free(tmp); md_free(tmp_mat); } } /* * Nuclear norm calculation for arbitrary block sizes */ float lrnucnorm(const struct operator_p_s* op, const complex float* src) { struct lrthresh_data_s* data = (struct lrthresh_data_s*)operator_p_get_data(op); long strs1[DIMS]; md_calc_strides(DIMS, strs1, data->dims_decom, 1); float nnorm = 0.; for (int l = 0; l < data->levels; l++) { const complex float* srcl = src + l * strs1[LEVEL_DIM]; long blkdims[DIMS]; long blksize = 1; for (unsigned int i = 0; i < DIMS; i++) { blkdims[i] = data->blkdims[l][i]; blksize *= blkdims[i]; } if (1 == blksize) { for (long j = 0; j < md_calc_size(DIMS, data->dims); j++) nnorm += 2 * cabsf(srcl[j]); continue; } struct svthresh_blockproc_data* svdata = svthresh_blockproc_create(data->mflags, 0., 0); complex float* tmp = md_alloc_sameplace(DIMS, data->dims, CFL_SIZE, src); //debug_print_dims(DP_DEBUG1, DIMS, data->dims); md_copy(DIMS, data->dims, tmp, srcl, CFL_SIZE); // Block SVD Threshold nnorm = blockproc(DIMS, data->dims, blkdims, (void*)svdata, nucnorm_blockproc, tmp, tmp); xfree(svdata); md_free(tmp); } return nnorm; } /************* * Block dimensions functions *************/ /** * Generates multiscale low rank block sizes * * @param blkdims - block sizes to be written * @param flags - specifies which dimensions to do the blocks. The other dimensions will be the same as input * @param idims - input dimensions * @param blkskip - scale each level by blkskip to generate the next level * * returns number of levels */ long multilr_blkdims(long blkdims[MAX_LEV][DIMS], unsigned long flags, const long idims[DIMS], int blkskip, long initblk) { // Multiscale low rank block sizes long tmp_block[DIMS]; for (unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(flags, i)) tmp_block[i] = MIN(initblk, idims[i]); else tmp_block[i] = idims[i]; } bool done; // Loop block_sizes long levels = 0; do { levels++; debug_printf(DP_INFO, "[\t"); for (unsigned int i = 0; i < DIMS; i++) { blkdims[levels - 1][i] = tmp_block[i]; debug_printf(DP_INFO, "%ld\t", blkdims[levels-1][i]); } debug_printf(DP_INFO, "]\n"); done = true; for (unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(flags, i) && (idims[i] != 1)) { tmp_block[i] = MIN(tmp_block[i] * blkskip, idims[i]); done = done && (blkdims[levels - 1][i] == idims[i]); } } } while(!done); return levels; } void add_lrnoiseblk(long* levels, long blkdims[MAX_LEV][DIMS], const long idims[DIMS]) { levels[0]++; debug_printf(DP_DEBUG1, "[\t"); for (unsigned int i = 0; i < DIMS; i++) { blkdims[levels[0] - 1][i] = idims[i]; debug_printf(DP_DEBUG1, "%ld\t", blkdims[levels[0] - 1][i]); } debug_printf(DP_DEBUG1, "]\n"); } /** * Generates locally low rank block sizes * * @param blkdims - block sizes to be written * @param flags - specifies which dimensions to do the blocks. The other dimensions will be the same as input * @param idims - input dimensions * @param llkblk - the block size * * returns number of levels = 1 */ long llr_blkdims(long blkdims[MAX_LEV][DIMS], unsigned long flags, const long idims[DIMS], long llrblk) { for (unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(flags, i)) blkdims[0][i] = MIN(llrblk, idims[i]); else blkdims[0][i] = idims[i]; } return 1; } /** * Generates low rank + sparse block sizes * * @param blkdims - block sizes to be written * @param idims - input dimensions * * returns number of levels = 2 */ long ls_blkdims(long blkdims[MAX_LEV][DIMS], const long idims[DIMS]) { for (unsigned int i = 0; i < DIMS; i++) { blkdims[0][i] = 1; blkdims[1][i] = idims[i]; } return 2; } float get_lrthresh_lambda(const struct operator_p_s* o) { auto data = CAST_DOWN(lrthresh_data_s, operator_p_get_data(o)); return data->lambda; } bart-0.5.00/src/lowrank/lrthresh.h000066400000000000000000000025071353046746100170110ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include "misc/mri.h" #ifndef MAX_LEV #define MAX_LEV 100 #endif struct operator_p_s; // Low rank thresholding for arbitrary block sizes extern const struct operator_p_s* lrthresh_create(const long dims_lev[DIMS], _Bool randshift, unsigned long mflags, const long blkdims[MAX_LEV][DIMS], float lambda, _Bool noise, int remove_mean, _Bool overlapping_blocks); // Returns nuclear norm using lrthresh operator extern float lrnucnorm(const struct operator_p_s* op, const complex float* src); // Generates multiscale block sizes extern long multilr_blkdims(long blkdims[MAX_LEV][DIMS], unsigned long flags, const long dims[DIMS], int blkskip, long initblk); // Generates locally low rank block size extern long llr_blkdims(long blkdims[MAX_LEV][DIMS], unsigned long flags, const long dims[DIMS], long llrblk); // Generates low rank plus sparse block size extern long ls_blkdims(long blkdims[MAX_LEV][DIMS], const long dims[DIMS]); extern void add_lrnoiseblk(long* level, long blkdims[MAX_LEV][DIMS], const long dims[DIMS]); // Return the regularization parameter extern float get_lrthresh_lambda(const struct operator_p_s* o); bart-0.5.00/src/lowrank/svthresh.c000066400000000000000000000145731353046746100170250ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong * 2014 Martin Uecker * */ #include #include #include #include #include #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/lapack.h" #include "num/blas.h" #include "num/linalg.h" #include "num/ops.h" #include "num/iovec.h" #include "num/fft.h" #include "iter/thresh.h" #include "svthresh.h" float svthresh_nomeanu( long M, long N, float lambda, complex float* dst, const complex float* src) { long MN = M*N; complex float* basis = md_alloc( 1, &M, CFL_SIZE ); complex float* coeff = md_alloc( 1, &N, CFL_SIZE ); complex float* tmp = md_alloc( 1, &MN, CFL_SIZE ); for( int i = 0; i < M; i++) basis[i] = 1./sqrtf( M ); md_clear( 1, &N, coeff, CFL_SIZE ); md_clear( 1, &MN, tmp, CFL_SIZE ); for( int j = 0; j < N; j++) for( int i = 0; i < M; i++) coeff[j] += basis[i] * src[i + j*M]; for( int j = 0; j < N; j++) for( int i = 0; i < M; i++) tmp[i + j*M] = src[i + j*M] - coeff[j] * basis[i]; svthresh(M, N, lambda , dst, tmp); for( int j = 0; j < N; j++) for( int i = 0; i < M; i++) dst[i + j*M] += coeff[j] * basis[i]; return 0; } float svthresh_nomeanv( long M, long N, float lambda, complex float* dst, const complex float* src) { long MN = M*N; complex float* basis = md_alloc( 1, &N, CFL_SIZE ); complex float* coeff = md_alloc( 1, &M, CFL_SIZE ); complex float* tmp = md_alloc( 1, &MN, CFL_SIZE ); for( int i = 0; i < N; i++) basis[i] = 1. / sqrtf( N ); md_clear( 1, &M, coeff, CFL_SIZE ); md_clear( 1, &MN, tmp, CFL_SIZE ); for( int j = 0; j < N; j++) for( int i = 0; i < M; i++) coeff[i] += basis[j] * src[i + j*M]; ; for( int j = 0; j < N; j++) for( int i = 0; i < M; i++) tmp[i + j*M] = src[i + j*M] - coeff[i] * basis[j]; svthresh(M, N, lambda , dst, tmp); for( int j = 0; j < N; j++) for( int i = 0; i < M; i++) dst[i + j*M] += coeff[i] * basis[j]; return 0; } /** * Singular Value Thresholding * * @param M - matrix column size * @param N - matrix row size * @param lambda - regularization parameter * @param A - input/output matrix */ float svthresh(long M, long N, float lambda, complex float* dst, const complex float* src) //FIXME: destroys input { long minMN = MIN(M,N); long dimsU[3] = {M,minMN,1}; long dimsVT[3] = {minMN,N,1}; long dimsS[3] = {minMN,1,1}; // long dimsAA[3] = {minMN, minMN,1}; long strsVT[3]; long strsS[3]; md_calc_strides(3, strsVT, dimsVT, CFL_SIZE); md_calc_strides(3, strsS, dimsS, FL_SIZE); complex float* U = md_alloc_sameplace(3, dimsU, CFL_SIZE, src); complex float* VT = md_alloc_sameplace(3, dimsVT, CFL_SIZE, src ); float* S = md_alloc_sameplace(3, dimsS, FL_SIZE, src); // complex float* AA = md_alloc_sameplace(3, dimsAA, CFL_SIZE, src ); // lapack_normal_multiply( M, N, (M > N), (complex float (*) [])AA, (const complex float (*) [])src ); // SVD lapack_svd_econ(M, N, (complex float (*) []) U, (complex float (*) []) VT, S, (complex float (*) [N])src); // Thresh S md_softthresh(3, dimsS, lambda, 0, S, S); // VT = S * VT md_mul2( 3, dimsVT, strsVT, (float*) VT, strsVT, (float*) VT, strsS, S ); md_mul2( 3, dimsVT, strsVT, ((float*) VT)+1, strsVT, ((float*) VT)+1, strsS, S ); // dst = U * VT blas_matrix_multiply( M, N, minMN, (complex float (*) [N])dst, (const complex float (*) [minMN])U, (const complex float (*) [N])VT ); md_free(U); md_free(VT); md_free(S); return 0; } float nuclearnorm(long M, long N, const complex float* d) { // FIXME: destroys input long minMN = MIN(M,N); long dimsU[3] = {M, minMN, 1}; long dimsVT[3] = {minMN, N, 1}; long dimsS[3] = {minMN, 1, 1}; complex float* U = md_alloc_sameplace(3, dimsU, CFL_SIZE, d); complex float* VT = md_alloc_sameplace(3, dimsVT, CFL_SIZE, d ); float* S = md_alloc_sameplace(3, dimsS, FL_SIZE, d); // SVD lapack_svd_econ(M, N, (complex float (*) []) U, (complex float (*) []) VT, S, (complex float (*) [N])d); float nnorm = 0.; for (int i = 0; i < minMN; i++) nnorm += S[i]; md_free(U); md_free(VT); md_free(S); return nnorm; } float maxsingular(long M, long N, const complex float* d) { // FIXME: destroys input long dimsU[2] = {M,N}; long dimsV[2] = {N,N}; complex float* U = md_alloc(2, dimsU, sizeof(complex float) ); complex float* VT = md_alloc(2, dimsV, sizeof(complex float) ); float* S = xmalloc( MIN(M,N) * sizeof(float) ); // SVD lapack_svd_econ(M, N, (complex float (*) []) U, (complex float (*) []) VT, S, (complex float (*) [N])d); float value = S[0]; md_free(U); md_free(VT); xfree(S); return value; } /*********** * Blockproc functions ************/ struct svthresh_blockproc_data { unsigned long mflags; float lambda; int remove_mean; }; struct svthresh_blockproc_data* svthresh_blockproc_create( unsigned long mflags, float lambda, int remove_mean ) { PTR_ALLOC(struct svthresh_blockproc_data, data); data->mflags = mflags; data->lambda = lambda; data->remove_mean = remove_mean; return data; } float svthresh_blockproc( const void* _data, const long blkdims[DIMS], complex float* dst, const complex float* src ) { const struct svthresh_blockproc_data* data = (const struct svthresh_blockproc_data*) _data; long M = 1; long N = md_calc_size( DIMS, blkdims ); for ( unsigned int i = 0; i < DIMS; i++ ) { if (MD_IS_SET(data->mflags, i)) { M *= blkdims[i]; N /= blkdims[i]; } } if (data->remove_mean == 1) svthresh_nomeanu(M, N, data->lambda , dst, src); else if (data->remove_mean == 2) svthresh_nomeanv(M, N, data->lambda , dst, src); else if (data->remove_mean == 0) svthresh(M, N, data->lambda , dst, src); else assert(0); return 0; } float nucnorm_blockproc( const void* _data, const long blkdims[DIMS], complex float* dst, const complex float* src ) { UNUSED(dst); const struct svthresh_blockproc_data* data = (const struct svthresh_blockproc_data*) _data; long M = 1; long N = md_calc_size( DIMS, blkdims ); for ( unsigned int i = 0; i < DIMS; i++ ) { if (MD_IS_SET(data->mflags, i)) { M *= blkdims[i]; N /= blkdims[i]; } } float G = sqrtf(M) + sqrtf(N); return G * nuclearnorm(M, N, src); } bart-0.5.00/src/lowrank/svthresh.h000066400000000000000000000030121353046746100170140ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #define GWIDTH( M, N, B) ( (sqrtf( M ) + sqrtf( N )) + sqrtf( logf( B * ((M > N) ? N : M )) )) //#define GWIDTH( M, N, B) ( sqrtf( M ) + sqrtf( N ) ) //#define GWIDTH( M, N, B) sqrtf( ((M > N) ? M : N) ) #include // Singular value thresholding for matrix extern float svthresh(long M, long N, float lambda, complex float* dst, const complex float* src); extern float svthresh2(long M, long N, float lambda, complex float* dst, const complex float* src, complex float* U, float* S, complex float* VT); extern float svthresh_nomeanu(long M, long N, float lambda, complex float* dst, const complex float* src); extern float svthresh_nomeanv(long M, long N, float lambda, complex float* dst, const complex float* src); // Singular value analysis (maybe useful to help determining regularization parameter for min nuclear norm) extern float nuclearnorm(long M, long N, const complex float* d); extern float maxsingular(long M, long N, const complex float* d); extern struct svthresh_blockproc_data* svthresh_blockproc_create(unsigned long mflags, float lambda, int remove_mean); extern float svthresh_blockproc(const void* _data, const long blkdims[DIMS], complex float* dst, const complex float* src); extern float nucnorm_blockproc(const void* _data, const long blkdims[DIMS], complex float* dst, const complex float* src); bart-0.5.00/src/lrmatrix.c000066400000000000000000000144631353046746100153420ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong * 2015-2016 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "num/ops_p.h" #include "num/ops.h" #include "linops/linop.h" #include "linops/sum.h" #include "linops/sampling.h" #include "linops/someops.h" #include "iter/iter.h" #include "iter/lsqr.h" #include "iter/thresh.h" #include "iter/prox.h" #include "lowrank/lrthresh.h" #include "misc/debug.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" struct s_data { INTERFACE(operator_data_t); long size; }; static DEF_TYPEID(s_data); // x = (z1 + z2)/2 static void sum_xupdate(const operator_data_t* _data, float rho, complex float* dst, const complex float* src) { UNUSED(rho); const struct s_data* data = CAST_DOWN(s_data, _data); for(int i = 0; i < data->size; i++) dst[i] = src[i] / 2.; } static void sum_xupdate_free(const operator_data_t* data) { xfree(CAST_DOWN(s_data, data)); } static const char usage_str[] = " "; static const char help_str[] = "Perform (multi-scale) low rank matrix completion"; int main_lrmatrix(int argc, char* argv[]) { double start_time = timestamp(); bool use_gpu = false; int maxiter = 100; float rho = 0.25; int blkskip = 2; bool randshift = true; long mflags = 1; long flags = ~0; const char* sum_str = NULL; bool noise = false; bool decom = false; bool llr = false; long llrblk = -1; bool ls = false; bool hogwild = false; bool fast = true; long initblk = 1; int remove_mean = 0; const struct opt_s opts[] = { OPT_SET('d', &decom, "perform decomposition instead, ie fully sampled"), // FIXME: 'd' fell through to u in original version ??!? OPT_INT('i', &maxiter, "iter", "maximum iterations."), OPT_LONG('m', &mflags, "flags", "which dimensions are reshaped to matrix columns."), OPT_LONG('f', &flags, "flags", "which dimensions to perform multi-scale partition."), OPT_INT('j', &blkskip, "scale", "block size scaling from one scale to the next one."), OPT_LONG('k', &initblk, "size", "smallest block size"), OPT_SET('N', &noise, "add noise scale to account for Gaussian noise."), OPT_SET('s', &ls, "perform low rank + sparse matrix completion."), OPT_LONG('l', &llrblk, "size", "perform locally low rank soft thresholding with specified block size."), OPT_STRING('o', &sum_str, "out2", "summed over all non-noise scales to create a denoised output."), OPT_SELECT('u', int, &remove_mean, 1, "()"), OPT_SELECT('v', int, &remove_mean, 2, "()"), OPT_SET('H', &hogwild, "(hogwild)"), OPT_FLOAT('p', &rho, "", "(rho)"), OPT_CLEAR('n', &randshift, "(no randshift)"), OPT_SET('g', &use_gpu, "(use GPU)"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); if (-1 != llrblk) llr = true; long idims[DIMS]; long odims[DIMS]; // Load input complex float* idata = load_cfl(argv[1], DIMS, idims); // Get levels and block dimensions long blkdims[MAX_LEV][DIMS]; long levels; if (llr) levels = llr_blkdims(blkdims, flags, idims, llrblk); else if (ls) levels = ls_blkdims(blkdims, idims); else levels = multilr_blkdims(blkdims, flags, idims, blkskip, initblk); if (noise) add_lrnoiseblk(&levels, blkdims, idims); debug_printf(DP_INFO, "Number of levels: %ld\n", levels); // Get outdims md_copy_dims(DIMS, odims, idims); odims[LEVEL_DIM] = levels; complex float* odata = create_cfl(argv[2], DIMS, odims); md_clear(DIMS, odims, odata, sizeof(complex float)); // Get pattern complex float* pattern = NULL; if (!decom) { pattern = md_alloc(DIMS, idims, CFL_SIZE); estimate_pattern(DIMS, idims, TIME_FLAG, pattern, idata); } // Initialize algorithm iter_conf* iconf; struct iter_admm_conf mmconf; memcpy(&mmconf, &iter_admm_defaults, sizeof(struct iter_admm_conf)); mmconf.maxiter = maxiter; mmconf.rho = rho; mmconf.hogwild = hogwild; mmconf.fast = fast; iconf = CAST_UP(&mmconf); // Initialize operators const struct linop_s* sum_op = linop_sum_create(odims); const struct linop_s* sampling_op = NULL; if (!decom) { sampling_op = linop_sampling_create(idims, idims, pattern); sum_op = linop_chain(sum_op, sampling_op); linop_free(sampling_op); } const struct operator_p_s* sum_prox = prox_lineq_create( sum_op, idata ); const struct operator_p_s* lr_prox = lrthresh_create(odims, randshift, mflags, (const long (*)[])blkdims, 1., noise, remove_mean, false); assert(use_gpu == false); (use_gpu ? num_init_gpu : num_init)(); if (use_gpu) debug_printf(DP_INFO, "GPU reconstruction\n"); // put into iter2 format unsigned int num_funs = 2; const struct linop_s* eye_op = linop_identity_create(DIMS, odims); const struct linop_s* ops[2] = { eye_op, eye_op }; const struct operator_p_s* prox_ops[2] = { sum_prox, lr_prox }; long size = 2 * md_calc_size(DIMS, odims); struct s_data s_data = { { &TYPEID(s_data) }, size / 2 }; const struct operator_p_s* sum_xupdate_op = operator_p_create(DIMS, odims, DIMS, odims, CAST_UP(&s_data), sum_xupdate, sum_xupdate_free); // do recon iter2_admm( iconf, NULL, num_funs, prox_ops, ops, NULL, sum_xupdate_op, size, (float*) odata, NULL, NULL); // Sum if (sum_str) { complex float* sdata = create_cfl(sum_str, DIMS, idims); long istrs[DIMS]; long ostrs[DIMS]; md_calc_strides(DIMS, istrs, idims, sizeof(complex float)); md_calc_strides(DIMS, ostrs, odims, sizeof(complex float)); md_clear(DIMS, idims, sdata, sizeof(complex float)); odims[LEVEL_DIM]--; md_zaxpy2(DIMS, odims, istrs, sdata, 1. / sqrt(levels), ostrs, odata); odims[LEVEL_DIM]++; unmap_cfl(DIMS, idims, sdata); } // Clean up unmap_cfl(DIMS, idims, idata); unmap_cfl(DIMS, odims, odata); linop_free(sum_op); operator_p_free(sum_prox); operator_p_free(lr_prox); double end_time = timestamp(); debug_printf(DP_INFO, "Total Time: %f\n", end_time - start_time); return 0; } bart-0.5.00/src/main.c000066400000000000000000000001631353046746100144140ustar00rootroot00000000000000 extern int main_real(int argc, char** argv); int main(int argc, char** argv) { return main_real(argc, argv); } bart-0.5.00/src/main.h000066400000000000000000000005071353046746100144230ustar00rootroot00000000000000 #include "misc/cppmap.h" #define DECLMAIN(x) \ extern int main_ ## x(int argc, char* argv[]); MAP(DECLMAIN, MAIN_LIST) #undef DECLMAIN extern int main_bart(int argc, char* argv[]); extern int main_bbox(int argc, char* argv[]); // for use as a library extern int bart_command(int len, char* buf, int argc, char* argv[]); bart-0.5.00/src/mandelbrot.c000066400000000000000000000041351353046746100156220ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "num/loop.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" #include "misc/opts.h" static const char usage_str[] = "output"; static const char help_str[] = "Compute mandelbrot set.\n"; int main_mandelbrot(int argc, char* argv[]) { unsigned int size = 512; unsigned int iter = 20; float zoom = .20; // 0.3 float thresh = 4.; float offr = 0.0; // 0.4 float offi = 0.0; const struct opt_s opts[] = { OPT_UINT('s', &size, "size", "image size"), OPT_UINT('n', &iter, "#", "nr. of iterations"), OPT_FLOAT('t', &thresh, "t", "threshold for divergence"), OPT_FLOAT('z', &zoom, "z", "zoom"), OPT_FLOAT('r', &offr, "r", "offset real"), OPT_FLOAT('i', &offi, "i", "offset imag"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); complex float off = offr + 1.i * offi; long dims[2] = { size, size }; complex float* o = create_cfl(argv[1], 2, dims); md_zfill(2, dims, o, iter); complex float* x = md_calloc(2, dims, CFL_SIZE); complex float* t = md_alloc(2, dims, CFL_SIZE); complex float* c = md_alloc(2, dims, CFL_SIZE); md_zgradient(2, dims, c, (complex float[2]){ 1., 1.i }); md_zfill(2, dims, t, (size / 2.) * (1. + 1.i + off)); md_zsub(2, dims, c, c, t); md_zsmul(2, dims, c, c, 1. / (zoom * size)); for (unsigned int i = 0; i < iter; i++) { // iteration x -> x * x + c md_zmul(2, dims, x, x, x); md_zadd(2, dims, x, x, c); // track non-divergent points md_zabs(2, dims, t, x); md_slessequal(3, (long[3]){ 2, dims[0], dims[1] }, (float*)t, (float*)t, thresh); md_zreal(2, dims, t, t); md_zsub(2, dims, o, o, t); } md_free(t); md_free(c); md_free(x); unmap_cfl(2, dims, o); return 0; } bart-0.5.00/src/mat2cfl.c000066400000000000000000000033441353046746100150240ustar00rootroot00000000000000/* * Martin Uecker 2012-01-18 * uecker@eecs.berkeley.edu * * Damien Nguyen 2018-04-19 * damien.nguyen@alumni.epfl.ch */ #include #include #include #include #include #include #include #include // MATLAB #include "mat.h" #include "matrix.h" #include "num/multind.h" #include "misc/mmio.h" int main(int argc, char *argv[]) { MATFile *mat; const char* name = NULL; const mwSize* dims; if (argc != 2) { fprintf(stderr, "Usage: %s file.mat\n", argv[0]); return 1; } if (NULL == (mat = matOpen(argv[1], "r"))) return 1; mxArray* ar; while (NULL != (ar = matGetNextVariable(mat, &name))) { int ndim = (int)mxGetNumberOfDimensions(ar); dims = mxGetDimensions(ar); bool cmp = mxIsComplex(ar); bool dbl = mxIsDouble(ar); printf("%s: [ ", name); if ((!cmp) || (!dbl)) { printf("not complex double\n"); mxDestroyArray(ar); continue; } long ldims[ndim]; for (int i = 0; i < ndim; i++) ldims[i] = dims[i]; for (int i = 0; i < ndim; i++) printf("%ld ", ldims[i]); char outname[256]; snprintf(outname, 256, "%s_%s", strtok(argv[1], "."), name); complex float* buf = create_cfl(outname, ndim, ldims); size_t size = md_calc_size(ndim, ldims); #if MX_HAS_INTERLEAVED_COMPLEX mxComplexDouble* x = mxGetComplexDoubles(ar); for (unsigned long i = 0; i < size; i++) buf[i] = x[i].real + 1.i * x[i].imag; #else double* re = mxGetPr(ar); double* im = mxGetPi(ar); for (unsigned long i = 0; i < size; i++) buf[i] = re[i] + 1.i * im[i]; #endif /* MX_HAS_INTERLEAVED_COMPLEX */ printf("] -> %s\n", outname); unmap_cfl(ndim, ldims, buf); mxDestroyArray(ar); } matClose(mat); } bart-0.5.00/src/mip.c000077500000000000000000000036521353046746100142660ustar00rootroot00000000000000/* Copyright 2014-2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2016 Jonathan Tamir */ #define _GNU_SOURCE #include #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/opts.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Maximum (minimum) intensity projection (MIP) along dimensions specified by bitmask.\n"; int main_mip(int argc, char* argv[argc]) { bool do_abs = false; bool mIP = false; const struct opt_s opts[] = { OPT_SET('m', &mIP, "minimum" ), OPT_SET('a', &do_abs, "do absolute value first" ), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int flags = atoi(argv[1]); long idims[DIMS]; complex float* in = load_cfl(argv[2], DIMS, idims); long odims[DIMS]; md_select_dims(DIMS, ~flags, odims, idims); complex float* out = create_cfl(argv[3], DIMS, odims); complex float* tmp = md_alloc(DIMS, idims, CFL_SIZE); if (do_abs) md_zabs(DIMS, idims, tmp, in); else md_copy(DIMS, idims, tmp, in, CFL_SIZE); long istr[DIMS]; long ostr[DIMS]; md_calc_strides(DIMS, istr, idims, CFL_SIZE); md_calc_strides(DIMS, ostr, odims, CFL_SIZE); md_clear(DIMS, odims, out, CFL_SIZE); md_max2(DIMS, idims, ostr, (float*)out, ostr, (const float*)out, istr, (const float*)tmp); if (mIP) { // need result of max in output md_min2(DIMS, idims, ostr, (float*)out, ostr, (const float*)out, istr, (const float*)tmp); } md_free(tmp); unmap_cfl(DIMS, idims, in); unmap_cfl(DIMS, odims, out); return 0; } bart-0.5.00/src/misc/000077500000000000000000000000001353046746100142575ustar00rootroot00000000000000bart-0.5.00/src/misc/Orchestra.cc000066400000000000000000000025271353046746100165260ustar00rootroot00000000000000/* Copyright 2018. Damien Nguyen * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Damien Nguyen */ #include "misc/debug.h" // Ideally we would copy the bare minimum code from the file below in order to // compile BART without requiring to include the header from Orchestra... #include // ============================================================================= extern "C" void vendor_log(int level, const char* func_name, const char* file, unsigned int line, const char* message) { TracePointer trace = Trace::Instance(); // TODO: the calls below definitely need some improvements to differentiate // between debugging level, as well as properly forwarding location // information to the logging backend if (-1 == debug_level) { char* str = getenv("DEBUG_LEVEL"); debug_level = (NULL != str) ? atoi(str) : DP_INFO; } if (level <= debug_level) { switch(level) { case DP_ERROR: trace->ConsoleMsg(message); break; case DP_WARN: trace->ConsoleMsg(message); break; case DP_INFO: trace->ConsoleMsg(message); break; default: trace->ConsoleMsg(message); } } } bart-0.5.00/src/misc/cppmap.h000066400000000000000000000026451353046746100157170ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Martin Uecker */ // some classic C preprocessor hackery /* Ideas from: * * https://github.com/swansontec/map-macro * https://github.com/pfultz2/Cloak/wiki/Is-the-C-preprocessor-Turing-complete%3F */ #define EMPTY() #define DEFER1(...) __VA_ARGS__ EMPTY() #define DEFER2(...) __VA_ARGS__ DEFER1(EMPTY)() #define DEFER3(...) __VA_ARGS__ DEFER2(EMPTY)() #define EXPAND6(...) __VA_ARGS__ #define EXPAND5(...) EXPAND6(EXPAND6(__VA_ARGS__)) #define EXPAND4(...) EXPAND5(EXPAND5(__VA_ARGS__)) #define EXPAND3(...) EXPAND4(EXPAND4(__VA_ARGS__)) #define EXPAND2(...) EXPAND3(EXPAND3(__VA_ARGS__)) #define EXPAND1(...) EXPAND2(EXPAND2(__VA_ARGS__)) #define EXPAND0(...) EXPAND1(EXPAND1(__VA_ARGS__)) #define EXPAND(...) EXPAND0(EXPAND0(__VA_ARGS__)) #define CAT0(x, y) x ## y #define CAT(x, y) CAT0(x, y) #define NIL_TEST() DUMMY, TRUE, #define RET2ND0(a, b, ...) b #define RET2ND(...) RET2ND0(__VA_ARGS__) #define NIL_P(x) RET2ND(NIL_TEST x, FALSE) #define IF_TRUE(a, b) a #define IF_FALSE(a, b) b #define IF(x, a, b) CAT(IF_, x)(a, b) #define MAP1() MAP0 #define MAP0(f, a, b, ...) f(a) IF(NIL_P(b), , DEFER3(MAP1)()(f, b, __VA_ARGS__)) #define MAP(f, ...) EXPAND(MAP0(f, __VA_ARGS__, ())) bart-0.5.00/src/misc/cppwrap.h000066400000000000000000000005321353046746100161040ustar00rootroot00000000000000 #ifndef __BART_CPP_WRAP #define __BART_CPP_WRAP #ifdef __cplusplus extern "C" { #endif #ifndef __VLA #ifdef __cplusplus #define __VLA(x) #else #define __VLA(x) static x #endif #endif #ifndef __VLA2 #ifdef __cplusplus #define __VLA2(x) #else #define __VLA2(x) x #endif #endif #else #undef __BART_CPP_WRAP #ifdef __cplusplus } #endif #endif bart-0.5.00/src/misc/debug.c000066400000000000000000000105021353046746100155070ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2016. Martin Uecker. * Copyright 2018. Damien Nguyen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2016 Martin Uecker * 2013,2015 Jonathan Tamir * 2013 Dara Bahri */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #ifndef __CYGWIN__ #include #endif #include "num/multind.h" #include "misc/mmio.h" #include "misc/cppmap.h" #include "misc/misc.h" #include "debug.h" #define STRSIZE 64 // Patrick Virtue's timing code double timestamp(void) { struct timeval tv; gettimeofday(&tv, 0); // more accurate than return tv.tv_sec + 1e-6 * tv.tv_usec; } void dump_cfl(const char* name, int D, const long dimensions[D], const complex float* src) { complex float* out = create_cfl(name, D, dimensions); md_copy(D, dimensions, out, src, sizeof(complex float)); unmap_cfl(D, dimensions, out); } int debug_level = -1; bool debug_logging = false; static const char* level_strings[] = { #define LSTR(x) [DP_ ## x] = # x, MAP(LSTR, ERROR, WARN, INFO, DEBUG1, DEBUG2, DEBUG3, DEBUG4, TRACE, ()) #undef LSTR }; static const char* get_level_str(int level) { assert(level >= 0); return (level < DP_ALL) ? level_strings[level] : "ALL"; } static void get_datetime_str(int len, char* datetime_str) { time_t tv = time(NULL); struct tm* dt = gmtime(&tv); strftime(datetime_str, len, "%F %T", dt); } #define RESET "\033[0m" #define RED "\033[31m" #ifdef REDEFINE_PRINTF_FOR_TRACE #undef debug_printf #undef debug_vprintf #endif void debug_vprintf(int level, const char* fmt, va_list ap) { if (-1 == debug_level) { char* str = getenv("DEBUG_LEVEL"); debug_level = (NULL != str) ? atoi(str) : DP_INFO; } if (level <= debug_level) { FILE* ofp = (level < DP_INFO) ? stderr : stdout; if (debug_logging) { char dt_str[STRSIZE]; get_datetime_str(STRSIZE, dt_str); fprintf(ofp, "[%s] [%s] - ", dt_str, get_level_str(level)); } else { if (level < DP_INFO) { fprintf(ofp, "%s%s: ", (level < DP_INFO ? RED : ""), get_level_str(level)); } } vfprintf(ofp, fmt, ap); if ((!debug_logging) && (level < DP_INFO)) { fprintf(ofp, RESET); } fflush(ofp); } } void debug_printf(int level, const char* fmt, ...) { va_list ap; va_start(ap, fmt); debug_vprintf(level, fmt, ap); va_end(ap); } void debug_vprintf_trace(const char* func_name, const char* file, unsigned int line, int level, const char* fmt, va_list ap) { #ifndef USE_LOG_BACKEND UNUSED(func_name); UNUSED(file); UNUSED(line); debug_vprintf(level, fmt, ap); #else char tmp[1024] = { 0 }; vsnprintf(tmp, 1023, fmt, ap); // take care of the trailing newline often present... if ('\n' == tmp[strlen(tmp) - 1]) tmp[strlen(tmp) - 1] = '\0'; vendor_log(level, func_name, file, line, tmp); #endif /* USE_LOG_BACKEND */ } void debug_printf_trace(const char* func_name, const char* file, unsigned int line, int level, const char* fmt, ...) { va_list ap; va_start(ap, fmt); debug_vprintf_trace(func_name, file, line, level, fmt, ap); va_end(ap); } void debug_backtrace(size_t n) { #ifndef __CYGWIN__ void* ptrs[n + 1]; size_t l = backtrace(ptrs, n + 1); if (l > 1) backtrace_symbols_fd(ptrs + 1, l - 1, STDERR_FILENO); #else UNUSED(n); debug_printf(DP_WARN, "no backtrace on cygwin."); #endif } void debug_trace(const char* fmt, ...) { debug_printf(DP_TRACE, "TRACE %f: ", timestamp()); va_list ap; va_start(ap, fmt); debug_vprintf(DP_TRACE, fmt, ap); va_end(ap); } #ifdef INSTRUMENT /* The following functions are called when entering or * leaving any function, if instrumentation is enabled with: * -finstrument-functions -finstrument-functions-exclude-file-list=debug.c */ extern void __cyg_profile_func_enter(void *this_fn, void *call_site) { UNUSED(call_site); debug_trace("ENTER %p\n", this_fn); } extern void __cyg_profile_func_exit(void *this_fn, void *call_site) { UNUSED(call_site); debug_trace("LEAVE %p\n", this_fn); } #endif bart-0.5.00/src/misc/debug.h000066400000000000000000000040431353046746100155170ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2016. Martin Uecker. * Copyright 2018. Damien Nguyen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __DEBUG_H #define __DEBUG_H 1 #include #include #include "misc/cppwrap.h" extern void dump_cfl(const char* name, int D, const long dimensions[__VLA(D)], const _Complex float* x); extern double timestamp(void); extern int debug_level; extern _Bool debug_logging; enum debug_levels { DP_ERROR, DP_WARN, DP_INFO, DP_DEBUG1, DP_DEBUG2, DP_DEBUG3, DP_DEBUG4, DP_TRACE, DP_ALL }; extern void debug_printf(int level, const char* fmt, ...); extern void debug_vprintf(int level, const char* fmt, va_list ap); #ifdef REDEFINE_PRINTF_FOR_TRACE #define debug_printf(level, ...) \ debug_printf_trace(__FUNCTION__, __FILE__, __LINE__, level, __VA_ARGS__) #define debug_vprintf(level, fmt, ap) \ debug_vprintf_trace(__FUNCTION__, __FILE__, __LINE__, level, fmt, ap) #endif extern void debug_printf_trace(const char* func_name, const char* file, unsigned int line, int level, const char* fmt, ...); extern void debug_vprintf_trace(const char* func_name, const char* file, unsigned int line, int level, const char* fmt, va_list ap); #define BART_OUT(...) debug_printf_trace(__FUNCTION__, __FILE__, __LINE__, DP_INFO, __VA_ARGS__) #define BART_ERR(...) debug_printf_trace(__FUNCTION__, __FILE__, __LINE__, DP_ERROR, __VA_ARGS__) #define BART_WARN(...) debug_printf_trace(__FUNCTION__, __FILE__, __LINE__, DP_WARN, __VA_ARGS__) extern void debug_backtrace(size_t n); extern void debug_trace(const char* fmt, ...); #define TRACE() debug_trace("%s:%d %s\n", __FILE__, __LINE__, __func__) #ifdef USE_LOG_BACKEND // this function must be provided by a vendor backend extern void vendor_log(int level, const char* func_name, const char* file, unsigned int line, const char* message); #endif #include "misc/cppwrap.h" #endif // __DEBUG_H bart-0.5.00/src/misc/dicom.c000066400000000000000000000147151353046746100155260ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2015 Martin Uecker * 2015 Jonathan Tamir */ /* NOTE: This code packs pixel data into very simple dicom images * with only image related tags. Other mandatory DICOM tags are * missing. We only support 16 bit little endian gray scale images. * * FOR RESEARCH USE ONLY - NOT FOR DIAGNOSTIC USE */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include "misc/misc.h" // for error #include "dicom.h" // US unsigned short // LS unsigned long // IS integer string // LT long text // CS code string // OW other word string #define DGRP_IMAGE 0x0028 #define DTAG_IMAGE_SAMPLES_PER_PIXEL 0x0002 #define DTAG_IMAGE_PHOTOM_INTER 0x0004 #define DTAG_IMAGE_ROWS 0x0010 #define DTAG_IMAGE_COLS 0x0011 #define DTAG_IMAGE_BITS_ALLOC 0x0100 #define DTAG_IMAGE_BITS_STORED 0x0101 #define DTAG_IMAGE_PIXEL_HIGH_BIT 0x0102 #define DTAG_IMAGE_PIXEL_REP 0x0103 // 0 unsigned 2 two's complement #define MONOCHROME2 "MONOCHROME2" #define DGRP_PIXEL 0x7FE0 #define DTAG_PIXEL_DATA 0x0010 #define DGRP_FILE 0x0002 #define DTAG_META_SIZE 0x0000 #define DTAG_TRANSFER_SYNTAX 0x0010 #define LITTLE_ENDIAN_EXPLICIT "1.2.840.10008.1.2.1" #define DGRP_IMAGE2 0x0020 #define DTAG_IMAGE_INSTANCE_NUM 0x0013 #define DTAG_COMMENT 0x4000 // order matters... enum eoffset { EOFF_BEGIN, ITAG_META_SIZE = EOFF_BEGIN, ITAG_TRANSFER_SYNTAX, ITAG_IMAGE_INSTANCE_NUM, ITAG_COMMENT, ITAG_IMAGE_SAMPLES_PER_PIXEL, ITAG_IMAGE_PHOTOM_INTER, ITAG_IMAGE_ROWS, ITAG_IMAGE_COLS, ITAG_IMAGE_BITS_ALLOC, ITAG_IMAGE_BITS_STORED, ITAG_IMAGE_PIXEL_HIGH_BIT, ITAG_IMAGE_PIXEL_REP, ITAG_PIXEL_DATA, EOFF_END, }; struct element { enum eoffset eoff; // sanity check uint16_t group; uint16_t element; char vr[2]; unsigned int len; const void* data; }; struct element dicom_elements_default[EOFF_END] = { { ITAG_META_SIZE, DGRP_FILE, DTAG_META_SIZE, "UL", 4, &(uint32_t){ 28 } }, { ITAG_TRANSFER_SYNTAX, DGRP_FILE, DTAG_TRANSFER_SYNTAX, "UI", sizeof(LITTLE_ENDIAN_EXPLICIT), LITTLE_ENDIAN_EXPLICIT }, { ITAG_IMAGE_INSTANCE_NUM, DGRP_IMAGE2, DTAG_IMAGE_INSTANCE_NUM, "IS", 0, NULL }, { ITAG_COMMENT, DGRP_IMAGE2, DTAG_COMMENT, "LT", 22, "NOT FOR DIAGNOSTIC USE\0\0" }, { ITAG_IMAGE_SAMPLES_PER_PIXEL, DGRP_IMAGE, DTAG_IMAGE_SAMPLES_PER_PIXEL, "US", 2, &(uint16_t){ 1 } }, // gray scale { ITAG_IMAGE_PHOTOM_INTER, DGRP_IMAGE, DTAG_IMAGE_PHOTOM_INTER, "CS", sizeof(MONOCHROME2), MONOCHROME2 }, // 0 is black { ITAG_IMAGE_ROWS, DGRP_IMAGE, DTAG_IMAGE_ROWS, "US", 2, &(uint16_t){ 0 } }, { ITAG_IMAGE_COLS, DGRP_IMAGE, DTAG_IMAGE_COLS, "US", 2, &(uint16_t){ 0 } }, { ITAG_IMAGE_BITS_ALLOC, DGRP_IMAGE, DTAG_IMAGE_BITS_ALLOC, "US", 2, &(uint16_t){ 16 } }, // { ITAG_IMAGE_BITS_STORED, DGRP_IMAGE, DTAG_IMAGE_BITS_STORED, "US", 2, &(uint16_t){ 16 } }, // 12 for CT { ITAG_IMAGE_PIXEL_HIGH_BIT, DGRP_IMAGE, DTAG_IMAGE_PIXEL_HIGH_BIT, "US", 2, &(uint16_t){ 15 } }, { ITAG_IMAGE_PIXEL_REP, DGRP_IMAGE, DTAG_IMAGE_PIXEL_REP, "US", 2, &(uint16_t){ 0 } }, // unsigned { ITAG_PIXEL_DATA, DGRP_PIXEL, DTAG_PIXEL_DATA, "OW", 0, NULL }, }; static bool vr_oneof(const char a[2], unsigned int N, const char b[N][2]) { for (unsigned int i = 0; i < N; i++) if ((a[0] == b[i][0]) && (a[1] == b[i][1])) return true; return false; } static int dicom_write_element(unsigned int len, char buf[static 8 + len], struct element e) { assert((((union { uint16_t s; uint8_t b; }){ 1 }).b)); // little endian assert(len == e.len); assert(0 == len % 2); int o = 0; buf[o++] = ((e.group >> 0) & 0xFF); buf[o++] = ((e.group >> 8) & 0xFF); buf[o++] = ((e.element >> 0) & 0xFF); buf[o++] = ((e.element >> 8) & 0xFF); buf[o++] = e.vr[0]; buf[o++] = e.vr[1]; if (!vr_oneof(e.vr, 5, (const char[5][2]){ "OB", "OW", "SQ", "UN", "UT" })) { buf[o++] = ((len >> 0) & 0xFF); buf[o++] = ((len >> 8) & 0xFF); } else { buf[o++] = 0; // reserved buf[o++] = 0; // reserved buf[o++] = ((len >> 0) & 0xFF); buf[o++] = ((len >> 8) & 0xFF); buf[o++] = ((len >> 16) & 0xFF); buf[o++] = ((len >> 24) & 0xFF); } memcpy(buf + o, e.data, len); return len + o; } int dicom_write(const char* name, unsigned int cols, unsigned int rows, long inum, const unsigned char* img) { int fd; void* addr; struct stat st; int ret = -1; // allocate before any goto calls int entries = EOFF_END; struct element dicom_elements[entries]; for (int i = 0; i < entries; i++) { memcpy(&dicom_elements[i], &dicom_elements_default[i], sizeof(struct element)); assert(dicom_elements[i].eoff == (enum eoffset)i); } if (-1 == (fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR))) goto cleanup; if (-1 == fstat(fd, &st)) goto cleanup; size_t size = 128 + 4; dicom_elements[ITAG_IMAGE_ROWS].data = &(uint16_t){ rows }; dicom_elements[ITAG_IMAGE_COLS].data = &(uint16_t){ cols }; char inst_num[12]; // max number of bytes for InstanceNumber tag sprintf(inst_num, "+%04ld", inum); dicom_elements[ITAG_IMAGE_INSTANCE_NUM].data = inst_num; dicom_elements[ITAG_IMAGE_INSTANCE_NUM].len = sizeof(inst_num); dicom_elements[ITAG_PIXEL_DATA].data = img; dicom_elements[ITAG_PIXEL_DATA].len = 2 * rows * cols; size += 4; // the pixel data element is larger for (int i = 0; i < entries; i++) size += 8 + dicom_elements[i].len; if (-1 == ftruncate(fd, size)) goto cleanup; if (MAP_FAILED == (addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0))) goto cleanup; // write header memset(addr, 0, 128); memcpy(addr + 128, "DICM", 4); size_t off = 128 + 4; uint16_t last_group = 0; uint16_t last_element = 0; // make sure tags are in ascending order for (int i = 0; i < entries; i++) { assert(((last_group == dicom_elements[i].group) && (last_element < dicom_elements[i].element)) || (last_group < dicom_elements[i].group)); last_group = dicom_elements[i].group; last_element = dicom_elements[i].element; off += dicom_write_element(dicom_elements[i].len, addr + off, dicom_elements[i]); } assert(0 == size - off); ret = 0; if (-1 == munmap((void*)addr, size)) error("abort!"); cleanup: if (-1 == close(fd)) error("abort!"); return ret; } bart-0.5.00/src/misc/dicom.h000066400000000000000000000001711353046746100155220ustar00rootroot00000000000000 extern int dicom_write(const char* name, unsigned int cols, unsigned int rows, long inum, const unsigned char* img); bart-0.5.00/src/misc/io.c000066400000000000000000000155731353046746100150450ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. * Copyright 2017-2018. Damien Nguyen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2017-2018 Damien Nguyen */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include "num/multind.h" #include "misc/version.h" #include "misc/misc.h" #include "misc/debug.h" #include "io.h" static void xdprintf(int fd, const char* fmt, ...) { va_list ap; va_start(ap, fmt); int ret = vdprintf(fd, fmt, ap); va_end(ap); if (ret < 0) error("Error writing.\n"); } struct iofile_s { const char* name; bool out; struct iofile_s* prev; }; static struct iofile_s* iofiles = NULL; static void io_register(const char* name, bool out) { const struct iofile_s* iop = iofiles; while (NULL != iop) { if (0 == strcmp(name, iop->name) && (out || iop->out)) debug_printf(DP_WARN, "Overwriting file: %s\n", name); iop = iop->prev; } PTR_ALLOC(struct iofile_s, ion); ion->name = strdup(name); ion->out = out; ion->prev = iofiles; iofiles = PTR_PASS(ion); } void io_register_input(const char* name) { io_register(name, false); } void io_register_output(const char* name) { io_register(name, true); } void io_unregister(const char* name) { struct iofile_s** iop = &iofiles; struct iofile_s* io; while (NULL != (io = *iop)) { if (0 == strcmp(name, io->name)) { *iop = io->prev; xfree(io->name); xfree(io); return; } iop = &io->prev; } } void io_memory_cleanup(void) { while (NULL != iofiles) io_unregister(iofiles->name); } int write_cfl_header(int fd, unsigned int n, const long dimensions[n]) { xdprintf(fd, "# Dimensions\n"); for (unsigned int i = 0; i < n; i++) xdprintf(fd, "%ld ", dimensions[i]); xdprintf(fd, "\n"); if (NULL != command_line) { xdprintf(fd, "# Command\n"); xdprintf(fd, "%s\n", command_line); } if (NULL != iofiles) { struct iofile_s* in = iofiles; xdprintf(fd, "# Files\n"); while (in) { xdprintf(fd, " %c%s", in->out ? '>' : '<', in->name); in = in->prev; } xdprintf(fd, "\n"); } xdprintf(fd, "# Creator\nBART %s\n", bart_version); return 0; } int read_cfl_header(int fd, unsigned int n, long dimensions[n]) { char header[4097]; memset(header, 0, 4097); int max; if (0 > (max = read(fd, header, 4096))) return -1; int pos = 0; int delta = 0; bool ok = false; while (true) { // skip lines not starting with '#' while ('#' != header[pos]) { if ('\0' == header[pos]) goto out; if (0 != sscanf(header + pos, "%*[^\n]\n%n", &delta)) return -1; if (0 == delta) goto out; pos += delta; } char keyword[32]; if (1 == sscanf(header + pos, "# %31s\n%n", keyword, &delta)) { pos += delta; if (0 == strcmp(keyword, "Dimensions")) { for (unsigned int i = 0; i < n; i++) dimensions[i] = 1; long val; unsigned int i = 0; while (1 == sscanf(header + pos, "%ld%n", &val, &delta)) { pos += delta; if (i < n) dimensions[i] = val; else if (1 != val) return -1; i++; } if (0 != sscanf(header + pos, "\n%n", &delta)) return -1; pos += delta; if (ok) return -1; ok = true; } } else { // skip this line if (0 != sscanf(header + pos, "%*[^\n]\n%n", &delta)) return -1; if (0 == delta) goto out; pos += delta; } } out: return ok ? 0 : -1; } int write_coo(int fd, unsigned int n, const long dimensions[n]) { char header[4096]; size_t len = ARRAY_SIZE(header); memset(header, 0, 4096); int pos = 0; int ret; ret = snprintf(header + pos, len, "Type: float\nDimensions: %d\n", n); if ((ret < 0) || ((unsigned int)ret >= len)) return -1; pos += ret; len -= ret; long start = 0; long stride = 1; for (unsigned int i = 0; i < n; i++) { long size = dimensions[i]; ret = snprintf(header + pos, len, "[%ld\t%ld\t%ld\t%ld]\n", start, stride * size, size, stride); if ((ret < 0) || ((unsigned int)ret >= len)) return -1; pos += ret; len -= ret; stride *= size; } if (4096 != write(fd, header, 4096)) return -1; return 0; } int read_coo(int fd, unsigned int n, long dimensions[n]) { char header[4096]; if (4096 != read(fd, header, 4096)) return -1; int pos = 0; int delta = 0; if (0 != sscanf(header + pos, "Type: float\n%n", &delta)) return -1; if (0 == delta) return -1; pos += delta; unsigned int dim; if (1 != sscanf(header + pos, "Dimensions: %d\n%n", &dim, &delta)) return -1; pos += delta; // if (n != dim) // return -1; for (unsigned int i = 0; i < n; i++) dimensions[i] = 1; for (unsigned int i = 0; i < dim; i++) { long val; if (1 != sscanf(header + pos, "[%*d %*d %ld %*d]\n%n", &val, &delta)) return -1; pos += delta; if (i < n) dimensions[i] = val; else if (1 != val) // fail if we have to many dimensions not equal 1 return -1; } return 0; } struct ra_hdr_s { uint64_t magic; uint64_t flags; uint64_t eltype; uint64_t elbyte; uint64_t size; uint64_t ndims; }; #define RA_MAGIC_NUMBER 0x7961727261776172ULL #define RA_FLAG_BIG_ENDIAN (1ULL << 0) enum ra_types { RA_TYPE_USER = 0, RA_TYPE_INT, RA_TYPE_UINT, RA_TYPE_FLOAT, RA_TYPE_COMPLEX, }; #define err_assert(x) ({ if (!(x)) { debug_printf(DP_ERROR, "%s", #x); return -1; } }) int read_ra(int fd, unsigned int n, long dimensions[n]) { struct ra_hdr_s header; if (sizeof(header) != read(fd, &header, sizeof(header))) return -1; err_assert(RA_MAGIC_NUMBER == header.magic); err_assert(!(header.flags & RA_FLAG_BIG_ENDIAN)); err_assert(RA_TYPE_COMPLEX == header.eltype); err_assert(sizeof(complex float) == header.elbyte); err_assert(header.ndims <= n); uint64_t dims[header.ndims]; if ((int)sizeof(dims) != read(fd, &dims, sizeof(dims))) return -1; md_singleton_dims(n, dimensions); for (unsigned int i = 0; i < header.ndims; i++) dimensions[i] = dims[i]; // this can overflow, but we check in mmio err_assert(header.size == md_calc_size(n, dimensions) * sizeof(complex float)); return 0; } int write_ra(int fd, unsigned int n, const long dimensions[n]) { struct ra_hdr_s header = { .magic = RA_MAGIC_NUMBER, .flags = 0ULL, .eltype = RA_TYPE_COMPLEX, .elbyte = sizeof(complex float), .size = md_calc_size(n, dimensions) * sizeof(complex float), .ndims = n, }; if (sizeof(header) != write(fd, &header, sizeof(header))) return -1; uint64_t dims[n]; for (unsigned int i = 0; i < n; i++) dims[i] = dimensions[i]; if ((int)sizeof(dims) != write(fd, &dims, sizeof(dims))) return -1; return 0; } bart-0.5.00/src/misc/io.h000066400000000000000000000013021353046746100150330ustar00rootroot00000000000000 #include "misc/cppwrap.h" extern int write_ra(int fd, unsigned int n, const long dimensions[__VLA(n)]); extern int read_ra(int fd, unsigned int n, long dimensions[__VLA(n)]); extern int write_coo(int fd, unsigned int n, const long dimensions[__VLA(n)]); extern int read_coo(int fd, unsigned int n, long dimensions[__VLA(n)]); extern int write_cfl_header(int fd, unsigned int n, const long dimensions[__VLA(n)]); extern int read_cfl_header(int fd, unsigned int D, long dimensions[__VLA(D)]); extern void io_register_input(const char* name); extern void io_register_output(const char* name); extern void io_unregister(const char* name); extern void io_memory_cleanup(void); #include "misc/cppwrap.h" bart-0.5.00/src/misc/misc.c000066400000000000000000000232231353046746100153600ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. * Copyright 2017. University of Oxford. * Copyright 2017-2018. Damien Nguyen * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2011-2018 Martin Uecker * 2017 Sofia Dimoudi * 2017-2018 Damien Nguyen */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #ifdef BART_WITH_PYTHON #include #endif #include "misc/debug.h" #include "misc/nested.h" #include "misc/opts.h" #include "misc.h" #ifndef isnanf #define isnanf(X) isnan(X) #endif struct error_jumper_s { bool initialized; jmp_buf buf; }; extern struct error_jumper_s error_jumper; // FIXME should not be extern struct error_jumper_s error_jumper = { .initialized = false }; void* xmalloc(size_t s) { void* p = malloc(s); if (NULL == p) error("Could not allocate memory.\n"); return p; } void xfree(const void* x) { free((void*)x); } void warn_nonnull_ptr(void* p) { void** p2 = p; if (NULL != *p2) { debug_printf(DP_WARN, "pointer not cleared: "); debug_backtrace(1); } } void error(const char* fmt, ...) { va_list ap; va_start(ap, fmt); #ifndef BART_WITH_PYTHON #ifdef USE_LOG_BACKEND debug_vprintf_trace("error", __FILE__, __LINE__, DP_ERROR, fmt, ap); #else debug_vprintf(DP_ERROR, fmt, ap); #endif #else char err[1024] = { 0 }; if (NULL == PyErr_Occurred()) { vsnprintf(err, 1023, fmt, ap); PyErr_SetString(PyExc_RuntimeError, err); } // No else required as the error indicator has already been set elsewhere #endif /* !BART_WITH_PYTHON */ va_end(ap); if (error_jumper.initialized) longjmp(error_jumper.buf, 1); exit(EXIT_FAILURE); } int error_catcher(int fun(int argc, char* argv[argc]), int argc, char* argv[argc]) { int ret = -1; error_jumper.initialized = true; if (0 == setjmp(error_jumper.buf)) ret = fun(argc, argv); error_jumper.initialized = false; return ret; } extern FILE* bart_output; FILE* bart_output = NULL; int bart_printf(const char* fmt, ...) { va_list ap; va_start(ap, fmt); FILE* out = bart_output; if (NULL == bart_output) out = stdout; int ret = vfprintf(out, fmt, ap); va_end(ap); return ret; } void print_dims(int D, const long dims[D]) { printf("["); for (int i = 0; i < D; i++) printf("%3ld ", dims[i]); printf("]\n"); } #ifdef REDEFINE_PRINTF_FOR_TRACE #undef debug_print_dims #endif void debug_print_dims(int dblevel, int D, const long dims[D]) { bool dbl = debug_logging; debug_logging = false; debug_printf(dblevel, "["); for (int i = 0; i < D; i++) debug_printf(dblevel, "%3ld ", dims[i]); debug_printf(dblevel, "]\n"); debug_logging = dbl; } void debug_print_dims_trace(const char* func_name, const char* file, unsigned int line, int dblevel, int D, const long dims[D]) { bool dbl = debug_logging; debug_logging = false; debug_printf_trace(func_name, file, line, dblevel, "["); for (int i = 0; i < D; i++) debug_printf_trace(func_name, file, line, dblevel, "%3ld ", dims[i]); debug_printf_trace(func_name, file, line, dblevel, "]\n"); debug_logging = dbl; } int parse_cfl(complex float res[1], const char* str) { char* tail; float re = strtof(str, &tail); float im = 0.; if (str == tail) return -1; if ('\0' == tail[0]) goto ok; if (('i' == tail[0]) && ('\0' == tail[1])) { im = re; re = 0; goto ok; } str = tail; im = strtof(str, &tail); if (('i' != tail[0]) || ('\0' != tail[1])) return -1; ok: res[0] = re + 1.i * im; return 0; } void quicksort(int N, int ord[N], const void* data, quicksort_cmp_t cmp) { if (N < 2) return; int pivot = ord[N / 2]; int l = 0; int h = N - 1; while (l <= h) { if (cmp(data, ord[l], pivot) < 0) { l++; continue; } if (cmp(data, ord[h], pivot) > 0) { h--; continue; } int swap = ord[l]; ord[l] = ord[h]; ord[h] = swap; l++; h--; } if (h + 1 > 0) quicksort(h + 1, ord, data, cmp); if (N > l) quicksort(N - l, ord + l, data, cmp); } /** * Quickselect adapted from §8.5 in Numerical Recipes in C, * The Art of Scientific Computing * Second Edition, William H. Press, 1992. * Sort descending of an array of floats, stop at k largest element. * * @param arr array of floats, input * @param n total number of elements in input array * @param k the rank of the element to be selected in the sort * * @returns the k-th largest float in the array * * @note In-place sort. The input array contents are not preserved in their original order. */ float quickselect(float *arr, unsigned int n, unsigned int k) { unsigned long i,ir,j,l,mid; float a; l=0; ir=n-1; for(;;) { if (ir <= l+1) { if (ir == l+1 && arr[ir] > arr[l]) { SWAP(arr[l],arr[ir], float); } return arr[k]; } else { mid=(l+ir) >> 1; SWAP(arr[mid],arr[l+1], float); if (arr[l] < arr[ir]) { SWAP(arr[l],arr[ir], float); } if (arr[l+1] < arr[ir]) { SWAP(arr[l+1],arr[ir], float); } if (arr[l] < arr[l+1]) { SWAP(arr[l],arr[l+1], float); } i=l+1; j=ir; a=arr[l+1]; for (;;) { do i++; while (arr[i] > a); do j--; while (arr[j] < a); if (j < i) break; SWAP(arr[i],arr[j], float); } arr[l+1]=arr[j]; arr[j]=a; if (j >= k) ir=j-1; if (j <= k) l=i; } } } /** * * Same as quickselect, but the input is a complex array * and the absolute value of the k-th largest element is returned. * Possibly faster for application to complex arrays. * */ float quickselect_complex(complex float *arr, unsigned int n, unsigned int k) { unsigned long i,ir,j,l,mid; float a; complex float ca; l=0; ir=n-1; for(;;) { if (ir <= l+1) { if (ir == l+1 && cabsf(arr[ir]) > cabsf(arr[l])) { SWAP(arr[l],arr[ir], complex float); } return cabsf(arr[k]); } else { mid=(l+ir) >> 1; SWAP(arr[mid],arr[l+1], complex float); if (cabsf(arr[l]) < cabsf(arr[ir])) { SWAP(arr[l],arr[ir], complex float); } if (cabsf(arr[l+1]) < cabsf(arr[ir])) { SWAP(arr[l+1],arr[ir], complex float); } if (cabsf(arr[l]) < cabsf(arr[l+1])) { SWAP(arr[l],arr[l+1], complex float); } i=l+1; j=ir; a=cabsf(arr[l+1]); ca = arr[l+1]; for (;;) { do i++; while (cabsf(arr[i]) > a); do j--; while (cabsf(arr[j]) < a); if (j < i) break; SWAP(arr[i],arr[j], complex float); } arr[l+1]=arr[j]; arr[j]=ca; if (j >= k) ir=j-1; if (j <= k) l=i; } } } static const char* quote(const char* str) { int i = 0; int j = 0; int c; bool flag = false; while ('\0' != (c = str[i++])) { if (isspace(c)) flag = true; switch (c) { case '\\': case '\'': case '"': case '$': j++; /* fall through */ default: break; } } if ((!flag) && (0 == j)) return strdup(str); int len = strlen(str); char (*qstr)[len + j + 3] = TYPE_ALLOC(char[len + j + 3]); i = 0; j = 0; (*qstr)[j++] = '\"'; while ('\0' != (c = str[i++])) { switch (c) { case '\\': case '\'': case '"': case '$': (*qstr)[j++] = '\''; /* fall through */ default: (*qstr)[j++] = c; } } (*qstr)[j++] = '\"'; (*qstr)[j++] = '\0'; return *qstr; } const char* command_line = NULL; void save_command_line(int argc, char* argv[]) { size_t len = 0; const char* qargv[argc]; for (int i = 0; i < argc; i++) { qargv[i] = quote(argv[i]); len += strlen(qargv[i]) + 1; } char (*buf)[len + 1] = TYPE_ALLOC(char[len + 1]); size_t pos = 0; for (int i = 0; i < argc; i++) { strcpy((*buf) + pos, qargv[i]); pos += strlen(qargv[i]); xfree(qargv[i]); (*buf)[pos++] = ' '; } (*buf)[pos] = '\0'; XFREE(command_line); command_line = (*buf); } void mini_cmdline(int* argcp, char* argv[], int expected_args, const char* usage_str, const char* help_str) { mini_cmdline_bool(argcp, argv, '\0', expected_args, usage_str, help_str); } bool mini_cmdline_bool(int* argcp, char* argv[], char flag_char, int expected_args, const char* usage_str, const char* help_str) { bool flag = false; struct opt_s opts[1] = { { flag_char, false, opt_set, &flag, NULL } }; char* help = strdup(help_str); int hlen = strlen(help); if ((hlen > 1) && ('\n' == help[hlen - 1])) help[hlen - 1] = '\0'; int min_args = expected_args; int max_args = expected_args; if (expected_args < 0) { min_args = -expected_args; max_args = 1000; } cmdline(argcp, argv, min_args, max_args, usage_str, help, 1, opts); xfree(help); return flag; } void print_long(unsigned int D, const long arr[D]) { for (unsigned int i = 0; i < D; i++) printf("arr[%i] = %ld\n", i, arr[i]); } void print_float(unsigned int D, const float arr[D]) { for (unsigned int i = 0; i < D; i++) printf("arr[%i] = %f\n", i, arr[i]); } void print_int(unsigned int D, const int arr[D]) { for (unsigned int i = 0; i < D; i++) printf("arr[%i] = %i\n", i, arr[i]); } void print_complex(unsigned int D, const complex float arr[D]) { for (unsigned int i = 0; i < D; i++) printf("arr[%i]: real = %f, imag = %f\n", i, crealf(arr[i]), cimagf(arr[i])); } unsigned int bitcount(unsigned long flags) { unsigned int N = 0; for (; flags > 0; N++) flags &= (flags - 1); return N; } __attribute__((optimize("-fno-finite-math-only"))) bool safe_isnanf(float x) { return isnanf(x); } __attribute__((optimize("-fno-finite-math-only"))) bool safe_isfinite(float x) { return (!isnan(x) && !isinf(x)); // return isfinite(x); <- is sometimes true when x is NaN. } bart-0.5.00/src/misc/misc.h000066400000000000000000000067441353046746100153760ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * Copyright 2017. University of Oxford. * Copyright 2017-2018. Damien Nguyen * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __MISC_H #define __MISC_H #include #include #include #include "misc/nested.h" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif #define MIN(x, y) ({ __typeof(x) __x = (x); __typeof(y) __y = (y); (__x < __y) ? __x : __y; }) #define MAX(x, y) ({ __typeof(x) __x = (x); __typeof(y) __y = (y); (__x > __y) ? __x : __y; }) #define UNUSED(x) (void)(x) #define MAKE_ARRAY(x, ...) ((__typeof__(x)[]){ x, __VA_ARGS__ }) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define SWAP(x, y, T) do { T temp = x; x = y; y = temp; } while (0) // for quickselect #include "misc/cppwrap.h" extern void* xmalloc(size_t s); extern void xfree(const void*); extern void warn_nonnull_ptr(void*); #define XMALLOC(x) (x = xmalloc(sizeof(*x))) #define XFREE(x) (xfree(x), x = NULL) #define _TYPE_ALLOC(T) ((T*)xmalloc(sizeof(T))) #define TYPE_ALLOC(T) _TYPE_ALLOC(__typeof__(T)) // #define TYPE_CHECK(T, x) ({ T* _ptr1 = 0; __typeof(x)* _ptr2 = _ptr1; (void)_ptr2; (x); }) #define _PTR_ALLOC(T, x) \ T* x __attribute__((cleanup(warn_nonnull_ptr))) = xmalloc(sizeof(T)) #define PTR_ALLOC(T, x) _PTR_ALLOC(__typeof__(T), x) #define PTR_FREE(x) XFREE(x) #define PTR_PASS(x) ({ __typeof__(x) __tmp = (x); (x) = NULL; __tmp; }) extern int parse_cfl(_Complex float res[1], const char* str); #ifndef __cplusplus extern noreturn void error(const char* str, ...); #else extern __attribute__((noreturn)) void error(const char* str, ...); #endif extern int error_catcher(int fun(int argc, char* argv[__VLA(argc)]), int argc, char* argv[__VLA(argc)]); extern int bart_printf(const char* fmt, ...); extern void print_dims(int D, const long dims[__VLA(D)]); extern void debug_print_dims(int dblevel, int D, const long dims[__VLA(D)]); #ifdef REDEFINE_PRINTF_FOR_TRACE #define debug_print_dims(...) \ debug_print_dims_trace(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) #endif extern void debug_print_dims_trace(const char* func_name, const char* file, unsigned int line, int dblevel, int D, const long dims[__VLA(D)]); typedef int (*quicksort_cmp_t)(const void* data, int a, int b); extern void quicksort(int N, int ord[__VLA(N)], const void* data, quicksort_cmp_t cmp); extern float quickselect(float *arr, unsigned int n, unsigned int k); extern float quickselect_complex(_Complex float *arr, unsigned int n, unsigned int k); extern void mini_cmdline(int* argcp, char* argv[], int expected_args, const char* usage_str, const char* help_str); extern _Bool mini_cmdline_bool(int* argcp, char* argv[], char flag_char, int expected_args, const char* usage_str, const char* help_str); extern void print_long(unsigned int D, const long arr[__VLA(D)]); extern void print_float(unsigned int D, const float arr[__VLA(D)]); extern void print_int(unsigned int D, const int arr[__VLA(D)]); extern void print_complex(unsigned int D, const _Complex float arr[__VLA(D)]); extern unsigned int bitcount(unsigned long flags); extern const char* command_line; extern void save_command_line(int argc, char* argv[__VLA(argc)]); extern _Bool safe_isnanf(float x); extern _Bool safe_isfinite(float x); #include "misc/cppwrap.h" #endif // __MISC_H bart-0.5.00/src/misc/mmio.c000066400000000000000000000267461353046746100154030ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2017 Martin Uecker * 2015 Jonathan Tamir */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include "num/multind.h" #include "misc/misc.h" #include "misc/io.h" #include "misc/debug.h" #include "mmio.h" #if defined(USE_MEM_CFL) || defined(MEMONLY_CFL) #include "mmiocc.hh" #endif // for BSD compatibility #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON #endif #ifdef BART_WITH_PYTHON # include #endif /* BART_WITH_PYTHON */ static void io_error(const char* fmt, ...) { va_list ap; va_start(ap, fmt); #ifndef BART_WITH_PYTHON #ifdef USE_LOG_BACKEND debug_vprintf_trace("error", __FILE__, __LINE__, DP_ERROR, fmt, ap); va_end(ap); #else vfprintf(stderr, fmt, ap); va_end(ap); fflush(stderr); perror(" "); #endif #else if (NULL == PyErr_Occurred()) { char err[1024] = { 0 }; vsnprintf(err, 1023, fmt, ap); va_end(ap); PyErr_SetString(PyExc_RuntimeError, err); } // No else required as the error indicator has already been set elsewhere #endif /* !BART_WITH_PYTHON */ error(""); // FIXME: we may leak open files descriptors... } #define err_assert(x) ({ if (!(x)) { debug_printf(DP_ERROR, "%s", #x); exit(EXIT_FAILURE); } }) static bool long_mul_overflow_p(long a, long b) { bool of = false; of |= (a > 0) && (b > 0) && (a > LONG_MAX / b); of |= (a > 0) && (b < 0) && (b < LONG_MIN / a); of |= (a < 0) && (b > 0) && (a < LONG_MIN / b); of |= (a < 0) && (b < 0) && (b < LONG_MAX / a); return of; } static long io_calc_size(unsigned int D, const long dims[D], size_t size) { if (0 == D) return size; long a = io_calc_size(D - 1, dims + 1, size); long b = dims[0]; if ((a < 0) || (b < 0)) return -1; if (long_mul_overflow_p(a, b)) return -1; return a * b; } complex float* load_zra(const char* name, unsigned int D, long dims[D]) { int fd; if (-1 == (fd = open(name, O_RDONLY))) io_error("Loading ra file %s", name); if (-1 == read_ra(fd, D, dims)) error("Loading ra file %s", name); long T; if (-1 == (T = io_calc_size(D, dims, sizeof(complex float)))) error("Loading ra file %s", name); void* addr; struct stat st; if (-1 == fstat(fd, &st)) io_error("Loading ra file %s", name); off_t header_size; if (-1 == (header_size = lseek(fd, 0, SEEK_CUR))) io_error("Loading ra file %s", name); // ra allows random stuff at the end if (T + header_size > st.st_size) error("Loading ra file %s", name); assert(header_size < 4096); if (MAP_FAILED == (addr = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0))) io_error("Loading ra file %s", name); if (-1 == close(fd)) io_error("Loading ra file %s", name); return (complex float*)(addr + header_size);; } static void* create_data(int ofd, size_t header_size, size_t size) { if (-1 == (ftruncate(ofd, size + header_size))) return NULL; size_t skip = header_size & ~4095UL; size_t off = header_size & 4095UL; void* addr; if (MAP_FAILED == (addr = mmap(NULL, size + off, PROT_READ|PROT_WRITE, MAP_SHARED, ofd, skip))) return NULL; return (char*)addr + off; } complex float* create_zra(const char* name, unsigned int D, const long dims[D]) { int ofd; if (-1 == (ofd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR))) io_error("Creating ra file %s", name); if (-1 == write_ra(ofd, D, dims)) error("Creating ra file %s", name); long T; if (-1 == (T = io_calc_size(D, dims, sizeof(complex float)))) error("Creating ra file %s", name); off_t header_size; if (-1 == (header_size = lseek(ofd, 0, SEEK_CUR))) io_error("Creating ra file %s", name); void* data; if (NULL == (data = create_data(ofd, header_size, T))) error("Creating ra file %s", name); if (-1 == close(ofd)) io_error("Creating ra file %s", name); return (complex float*)data; } float* create_coo(const char* name, unsigned int D, const long dims[D]) { int ofd; if (-1 == (ofd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR))) io_error("Creating coo file %s", name); if (-1 == write_coo(ofd, D, dims)) error("Creating coo file %s", name); long T; if (-1 == (T = io_calc_size(D, dims, sizeof(float)))) error("Creating coo file %s", name); void* addr; if (NULL == (addr = create_data(ofd, 4096, T))) error("Creating coo file %s", name); if (-1 == close(ofd)) io_error("Creating coo file %s", name); return (float*)addr; } complex float* create_zcoo(const char* name, unsigned int D, const long dimensions[D]) { long dims[D + 1]; dims[0] = 2; // complex memcpy(dims + 1, dimensions, D * sizeof(long)); return (complex float*)create_coo(name, D + 1, dims); } complex float* create_cfl(const char* name, unsigned int D, const long dimensions[D]) { io_register_output(name); #ifdef MEMONLY_CFL return create_mem_cfl(name, D, dimensions); #else const char *p = strrchr(name, '.'); if ((NULL != p) && (p != name) && (0 == strcmp(p, ".ra"))) return create_zra(name, D, dimensions); if ((NULL != p) && (p != name) && (0 == strcmp(p, ".coo"))) return create_zcoo(name, D, dimensions); #ifdef USE_MEM_CFL if ((NULL != p) && (p != name) && (0 == strcmp(p, ".mem"))) return create_mem_cfl(name, D, dimensions); #endif char name_bdy[1024]; if (1024 <= snprintf(name_bdy, 1024, "%s.cfl", name)) error("Creating cfl file %s", name); char name_hdr[1024]; if (1024 <= snprintf(name_hdr, 1024, "%s.hdr", name)) error("Creating cfl file %s", name); int ofd; if (-1 == (ofd = open(name_hdr, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR))) io_error("Creating cfl file %s", name); if (-1 == write_cfl_header(ofd, D, dimensions)) error("Creating cfl file %s", name); if (-1 == close(ofd)) io_error("Creating cfl file %s", name); return shared_cfl(D, dimensions, name_bdy); #endif /* MEMONLY_CFL */ } float* load_coo(const char* name, unsigned int D, long dims[D]) { int fd; if (-1 == (fd = open(name, O_RDONLY))) io_error("Loading coo file %s", name); if (-1 == read_coo(fd, D, dims)) error("Loading coo file %s", name); long T; if (-1 == (T = io_calc_size(D, dims, sizeof(float)))) error("Loading coo file %s", name); void* addr; struct stat st; if (-1 == fstat(fd, &st)) io_error("Loading coo file %s", name); if (T + 4096 != st.st_size) error("Loading coo file %s", name); if (MAP_FAILED == (addr = mmap(NULL, T, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 4096))) io_error("Loading coo file %s", name); if (-1 == close(fd)) io_error("Loading coo file %s", name); return (float*)addr; } complex float* load_zcoo(const char* name, unsigned int D, long dimensions[D]) { long dims[D + 1]; float* data = load_coo(name, D + 1, dims); if (2 != dims[0]) error("Loading coo file %s", name); memcpy(dimensions, dims + 1, D * sizeof(long)); return (complex float*)data; } static complex float* load_cfl_internal(const char* name, unsigned int D, long dimensions[D], bool priv) { io_register_input(name); #ifdef MEMONLY_CFL UNUSED(priv); complex float* ptr = load_mem_cfl(name, D, dimensions); if (NULL == ptr) io_error("Loading in-memory cfl file %s", name); return ptr; #else const char *p = strrchr(name, '.'); if ((NULL != p) && (p != name) && (0 == strcmp(p, ".ra"))) return load_zra(name, D, dimensions); if ((NULL != p) && (p != name) && (0 == strcmp(p, ".coo"))) return load_zcoo(name, D, dimensions); #ifdef USE_MEM_CFL if ((NULL != p) && (p != name) && (0 == strcmp(p, ".mem"))) { complex float* ptr = load_mem_cfl(name, D, dimensions); if (ptr == NULL) { io_error("failed loading memory cfl file \"%s\"", name); } else { return ptr; } } #endif /* USE_MEM_CFL */ char name_bdy[1024]; if (1024 <= snprintf(name_bdy, 1024, "%s.cfl", name)) error("Loading cfl file %s", name); char name_hdr[1024]; if (1024 <= snprintf(name_hdr, 1024, "%s.hdr", name)) error("Loading cfl file %s", name); int ofd; if (-1 == (ofd = open(name_hdr, O_RDONLY))) io_error("Loading cfl file %s", name); if (-1 == read_cfl_header(ofd, D, dimensions)) error("Loading cfl file %s", name); if (-1 == close(ofd)) io_error("Loading cfl file %s", name); return (priv ? private_cfl : shared_cfl)(D, dimensions, name_bdy); #endif /* MEMONLY_CFL */ } complex float* load_cfl(const char* name, unsigned int D, long dimensions[D]) { return load_cfl_internal(name, D, dimensions, true); } complex float* load_shared_cfl(const char* name, unsigned int D, long dimensions[D]) { return load_cfl_internal(name, D, dimensions, false); } #ifndef MEMONLY_CFL complex float* shared_cfl(unsigned int D, const long dims[D], const char* name) { // struct stat st; int fd; void* addr; long T; if (-1 == (T = io_calc_size(D, dims, sizeof(complex float)))) error("shared cfl %s", name); err_assert(T > 0); if (-1 == (fd = open(name, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR))) io_error("shared cfl %s", name); // if (-1 == (fstat(fd, &st))) // error("abort"); // if (!((0 == st.st_size) || (T == st.st_size))) // error("abort"); if (NULL == (addr = create_data(fd, 0, T))) error("shared cfl %s", name); if (-1 == close(fd)) io_error("shared cfl %s", name); return (complex float*)addr; } #endif /* !MEMONLY_CFL */ complex float* anon_cfl(const char* name, unsigned int D, const long dims[D]) { UNUSED(name); #ifndef MEMONLY_CFL void* addr; long T; if (-1 == (T = io_calc_size(D, dims, sizeof(complex float)))) error("anon cfl"); if (MAP_FAILED == (addr = mmap(NULL, T, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0))) io_error("anon cfl"); return (complex float*)addr; #else return create_anon_mem_cfl(D, dims); #endif } #if 0 void* private_raw(size_t* size, const char* name) { int fd; void* addr; struct stat st; if (-1 == (fd = open(name, O_RDONLY))) error("abort"); if (-1 == (fstat(fd, &st))) error("abort"); *size = st.st_size; if (MAP_FAILED == (addr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0))) error("abort"); if (-1 == close(fd)) error("abort"); return addr; } #endif #ifndef MEMONLY_CFL complex float* private_cfl(unsigned int D, const long dims[D], const char* name) { long T; if (-1 == (T = io_calc_size(D, dims, sizeof(complex float)))) error("private cfl %s", name); int fd; void* addr; struct stat st; if (-1 == (fd = open(name, O_RDONLY))) io_error("private cfl %s", name); if (-1 == (fstat(fd, &st))) io_error("private cfl %s", name); if (T != st.st_size) error("private cfl %s", name); if (MAP_FAILED == (addr = mmap(NULL, T, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0))) io_error("private cfl %s", name); if (-1 == close(fd)) io_error("private cfl %s", name); return (complex float*)addr; } #endif /* !MEMONLY_CFL */ void unmap_cfl(unsigned int D, const long dims[D], const complex float* x) { #ifdef MEMONLY_CFL UNUSED(D); UNUSED(dims); try_delete_mem_cfl(x); #else #ifdef USE_MEM_CFL if (is_mem_cfl(x)) { // only delete if the dirty flag has been set try_delete_mem_cfl(x); return; } #endif long T; if (-1 == (T = io_calc_size(D, dims, sizeof(complex float)))) error("unmap cfl"); if (-1 == munmap((void*)((uintptr_t)x & ~4095UL), T)) io_error("unmap cfl"); #endif } bart-0.5.00/src/misc/mmio.h000066400000000000000000000031021353046746100153650ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" // extern void* private_raw(size_t* size, const char* name); #ifndef MEMONLY_CFL extern _Complex float* shared_cfl(unsigned int D, const long dims[__VLA(D)], const char* name); extern _Complex float* private_cfl(unsigned int D, const long dims[__VLA(D)], const char* name); #endif /* !MEMONLY_CFL */ extern void unmap_cfl(unsigned int D, const long dims[__VLA(D)], const _Complex float* x); extern _Complex float* anon_cfl(const char* name, unsigned int D, const long dims[__VLA(D)]); extern _Complex float* create_cfl(const char* name, unsigned int D, const long dimensions[__VLA(D)]); extern _Complex float* load_cfl(const char* name, unsigned int D, long dimensions[__VLA(D)]); extern _Complex float* load_shared_cfl(const char* name, unsigned int D, long dimensions[__VLA(D)]); extern float* create_coo(const char* name, unsigned int D, const long dimensions[__VLA(D)]); extern float* load_coo(const char* name, unsigned int D, long dimensions[__VLA(D)]); extern _Complex float* create_zcoo(const char* name, unsigned int D, const long dimensions[__VLA(D)]); extern _Complex float* load_zcoo(const char* name, unsigned int D, long dimensions[__VLA(D)]); extern _Complex float* create_zra(const char* name, unsigned int D, const long dims[__VLA(D)]); extern _Complex float* load_zra(const char* name, unsigned int D, long dims[__VLA(D)]); #include "misc/cppwrap.h" bart-0.5.00/src/misc/mmiocc.cc000066400000000000000000000423051353046746100160410ustar00rootroot00000000000000/* Copyright 2017-2018. Damien Nguyen. * Copyright 2017-2018. Francesco Santini * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Nguyen Damien * 2017-2018 Francesco Santini */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif /* !_GNU_SOURCE */ #ifdef BART_WITH_PYTHON # include # define PY_ARRAY_UNIQUE_SYMBOL bart_numpy_identifier # define NO_IMPORT_ARRAY # define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION # include # include "pybind11/pybind11.h" # include "pybind11/numpy.h" namespace py = pybind11; using numpy_farray_t = py::array_t, py::array::f_style | py::array::forcecast>; using numpy_array_t = py::array_t, py::array::c_style | py::array::forcecast>; #endif /* BART_WITH_PYTHON */ #include #include #include #include #include #include #include #include #include #include #include "num/multind.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/io.h" #include "mmiocc.hh" #define DIMS_MAX 32U // instead of 16 because of squeeze.c typedef _Complex float cx_float; // ======================================================================== #ifdef BART_WITH_PYTHON extern void* load_mem_cfl_python(const char* name, unsigned int D, long dimensions[]); #endif /* BART_WITH_PYTHON */ // ======================================================================== namespace internal_ { enum DATA_DIRECTION { INPUT, OUTPUT }; class Node { public: Node(const std::string& name) : name_(name) , dirty_(name.empty() ? true : false) , direction_(OUTPUT) { std::fill(dims_, dims_+DIMS_MAX, 1); } Node(const Node&) = delete; Node(Node&&) = delete; Node& operator=(const Node&) = delete; Node& operator=(Node&&) = delete; virtual ~Node() {} virtual std::string name() const { return name_; } virtual const long* dims() { return dims_; } virtual void* data() = 0; virtual const void* data() const = 0; virtual DATA_DIRECTION& data_dir() { return direction_; } virtual bool& dirty() { return dirty_; } virtual void clear_flags() { dirty_ = false; direction_ = OUTPUT; } protected: std::string name_; bool dirty_; DATA_DIRECTION direction_; long dims_[DIMS_MAX]; }; // ------------------------------------------------------------------------ struct cpp_deleter_t { template static void deallocate(T* data) { delete[] data; } }; struct c_deleter_t { template static void deallocate(T* data) { xfree(data); } }; struct noop_deleter_t { template static void deallocate(T*) {} }; // ------------------------------------------------------------------------ template class PointerNode : public Node { public: PointerNode(const std::string& name, unsigned int D, long dims[]) : PointerNode(name, D, dims, new cx_float[md_calc_size(D, dims)]) {} PointerNode(const std::string& name, unsigned int D, long dims[], T* ptr) : Node(name) , ptr_(ptr) { std::copy(dims, dims+D, dims_); } virtual ~PointerNode() { debug_printf(DP_DEBUG2, "in: PointerNode::~PointerNode()\n"); debug_printf(DP_DEBUG2, " deleting %s node\n", name_.empty() ? "anonymous" : ("\"" + name_ + "\"").c_str()); deleter_t::deallocate(ptr_); ptr_ = nullptr; } virtual void* data() override { return ptr_; } virtual const void* data() const override { return ptr_; } private: T* ptr_; }; // ------------------------------------------------------------------------ #ifdef BART_WITH_PYTHON // https://stackoverflow.com/questions/2828738/c-warning-declared-with-greater-visibility-than-the-type-of-its-field #pragma GCC visibility push(hidden) class PyPointerNode : public Node { public: PyPointerNode(const std::string& name, const numpy_farray_t& array) : Node(name) , array_(array) {} virtual ~PyPointerNode() { debug_printf(DP_DEBUG2, "in: PyPointerNode::~PyPointerNode()\n"); debug_printf(DP_DEBUG2, " deleting %s node\n", name_.empty() ? "anonymous" : ("\"" + name_ + "\"").c_str()); } virtual const long* dims() override { const auto* npy_dims(array_.shape()); debug_printf(DP_DEBUG2, " reading dimensions from Python object\n"); std::fill(dims_, dims_+DIMS_MAX, 1); std::copy(npy_dims, npy_dims + std::min(array_.ndim(), py::ssize_t(DIMS_MAX)), dims_); return dims_; } virtual void* data() override { return array_.mutable_data(); } virtual const void* data() const override { return array_.data(); } private: /* * Since we copied the input array into this PyPointerNode, its * reference count was automatically increased by pybind11 * so that even if the user deletes it, the memory stays valid */ numpy_farray_t array_; }; #pragma GCC visibility pop #endif /* BART_WITH_PYTHON */ // ------------------------------------------------------------------------ class NameEqual { public: NameEqual(const std::string& name) : name_(name) {} template auto operator() (const node_t& node) const { return name_ == node->name(); } private: std::string name_; }; class PtrDataEqual { public: PtrDataEqual(const void* ptr) : ptr_(ptr) {} template auto operator() (const node_t& node) const { return (ptr_ != nullptr) && (ptr_ == node->data()); } private: const void* ptr_; }; // ======================================================================== class MemoryHandler { typedef std::vector> vector_t; public: MemoryHandler() = default; ~MemoryHandler() = default; MemoryHandler(const MemoryHandler&) = delete; MemoryHandler& operator=(const MemoryHandler&) = delete; template T* allocate_mem_cfl(const std::string& name, unsigned int D, long dims[]) { debug_printf(DP_DEBUG2, "in: MemoryHandler::allocate_mem_cfl(\"%s\", %d, ...)\n", name.c_str(), D); const auto it(std::find_if(list_.begin(), list_.end(), NameEqual(name))); bool is_dirty(false); if (it != list_.end()) { debug_printf(DP_DEBUG2, " found \"%s\" already in the database!\n", name.c_str()); /* We are attempting to create a new memory CFL * but found that another one with the same name * already exists. * Now either: * - the mem CFL has previously been marked as input, * in which case we mark the existing one as dirty * - it is still marked as output, in which case we * delete the existing one * */ if ((*it)->data_dir() == INPUT) { BART_OUT("MEMCFL: marking first occurrence of %s as DIRTY!\n", (*it)->name().c_str()); (*it)->dirty() = true; is_dirty = true; std::iter_swap(it, list_.end()-1); // move it to the end } else { BART_OUT("MEMCFL: deleting first occurrence of %s\n", (*it)->name().c_str()); remove_node_(it); } } debug_printf(DP_DEBUG2, " allocating PointerNode\n"); list_.emplace_back(std::make_unique>(name, D, dims)); auto* data = reinterpret_cast(list_.back()->data()); if (is_dirty) { /* * Make sure the dirty node is after the one we just added * NB: cannot use 'it' here as a re-allocation might have * happened... */ std::iter_swap(list_.end()-2, list_.end()-1); } debug_printf(DP_DEBUG2, " returning from MemoryHandler::allocate_mem_cfl\n"); return data; } template T* allocate_mem_cfl(unsigned int D, long dims[]) { debug_printf(DP_DEBUG2, "in: MemoryHandler::allocate_mem_cfl(%d, ...)\n", D); debug_printf(DP_DEBUG2, " allocating PointerNode\n"); list_.emplace_back(std::make_unique>("", D, dims)); debug_printf(DP_DEBUG2, " returning from MemoryHandler::allocate_mem_cfl\n"); return reinterpret_cast(list_.back()->data()); } template void register_mem_cfl(const std::string& name, unsigned int D, long dims[], T* ptr, deleter_t) { debug_printf(DP_DEBUG2, "in: MemoryHandler::register_mem_cfl(\"%s\", ...)\n", name.c_str()); auto it(std::find_if(list_.begin(), list_.end(), NameEqual(name))); if (it != list_.end()) { debug_printf(DP_DEBUG2, "In-mem CFL: found existing data with the same name, deleting old data\n"); remove_node_(it); } it = std::find_if(list_.begin(), list_.end(), PtrDataEqual(ptr)); if (it != list_.end()) { error("In-mem CFL: attempting to register ptr for %s, " "but ptr has alread been registered for %s!\n", name.c_str(), (*it)->name().c_str()); } // Need to call io_register_input here since no calls to // either create_cfl() or load_cfl() lead to here... io_register_input(name.c_str()); list_.emplace_back(std::make_unique>(name, D, dims, ptr)); list_.back()->data_dir() = INPUT; } #ifdef BART_WITH_PYTHON void register_mem_cfl(const std::string& name, const numpy_farray_t& array) { debug_printf(DP_DEBUG2, "in: MemoryHandler::register_mem_cfl(\"%s\", npy_data)\n", name.c_str()); auto it(std::find_if(list_.begin(), list_.end(), NameEqual(name))); if (it != list_.end()) { debug_printf(DP_DEBUG2, "In-mem CFL: found existing data with the same name, deleting old data\n"); remove_node_(it); } it = std::find_if(list_.begin(), list_.end(), PtrDataEqual(array.data())); if (it != list_.end()) { char buf[1024] = { '\0' }; snprintf(buf, 1024, "In-mem CFL: attempting to register ptr for %s, " "but ptr has alread been registered for %s!\n", name.c_str(), (*it)->name().c_str()); throw std::runtime_error(buf); } // Need to call io_register_input here since no calls to // either create_cfl() or load_cfl() lead to here... io_register_input(name.c_str()); list_.emplace_back(std::make_unique(name, array)); list_.back()->data_dir() = INPUT; } #endif /* BART_WITH_PYTHON */ cx_float* load_mem_cfl(const std::string& name, unsigned int D, long dims[]) { debug_printf(DP_DEBUG2, "in: MemoryHandler::load_mem_cfl (\"%s\", ...)\n", name.c_str()); const auto it(std::find_if(list_.begin(), list_.end(), NameEqual(name))); if (it != list_.end()) { debug_printf(DP_DEBUG2, " found it! copying dimensions\n"); auto* d = (*it)->dims(); std::copy(d, d + std::min(D, DIMS_MAX), dims); debug_printf(DP_DEBUG2, " marking it as input\n"); (*it)->data_dir() = INPUT; debug_printf(DP_DEBUG2, " returning from MemoryHandler::load_mem_cfl\n"); return reinterpret_cast((*it)->data()); } else { return nullptr; } } template auto is_mem_cfl(T* ptr) { return std::find_if(list_.cbegin(), list_.cend(), PtrDataEqual(ptr)) != list_.cend(); } template auto try_delete_mem_cfl(T* ptr) { debug_printf(DP_DEBUG2, "in: MemoryHandler::try_delete_mem_cfl\n"); const auto it(std::find_if(list_.begin(), list_.end(), PtrDataEqual(ptr))); if (it != list_.end()) { debug_printf(DP_DEBUG2, " found data (%s)!\n", (*it)->name().empty() ? "anonymous" : ("\"" + (*it)->name() + "\"").c_str()); if ((*it)->dirty()) { debug_printf(DP_DEBUG2, " node is dirty, deallocating!\n"); remove_node_(it); } else { debug_printf(DP_DEBUG2, " node is ok, calling io_unregister(...) and clear_flags(...)\n"); io_unregister((*it)->name().c_str()); (*it)->clear_flags(); } return true; } debug_printf(DP_DEBUG2, " data *not* found!\n"); return false; } // Attempt to deallocate memory based on address or name template std::enable_if_t< !std::is_same< char, std::remove_reference_t>>::value, bool> remove(T* ptr) { return remove_(PtrDataEqual(ptr)); } bool remove(const std::string& name) { return remove_(NameEqual(name)); } void clear() { list_.clear(); } private: void remove_node_(vector_t::iterator it) { list_.erase(it); } // Return true if deletion occurred, false otherwise template bool remove_(unop_t op) { auto it = std::remove_if(list_.begin(), list_.end(), op); if (it != list_.end()) { list_.erase(it, list_.end()); return true; } return false; } vector_t list_; }; } // namespace internal_ typedef internal_::c_deleter_t c_delete; typedef internal_::cpp_deleter_t cpp_delete; typedef internal_::noop_deleter_t noop_delete; static internal_::MemoryHandler mem_handler; // ============================================================================= void* create_mem_cfl(const char* name, unsigned int D, const long dims[]) { debug_printf(DP_DEBUG2, "in: create_mem_cfl\n"); if (D > DIMS_MAX) { BART_WARN("create_mem_cfl: D > DIMS_MAX: %d > %d!\n", D, DIMS_MAX); } return mem_handler.allocate_mem_cfl(name, D, const_cast(dims)); } void* create_anon_mem_cfl(unsigned int D, const long dims[]) { debug_printf(DP_DEBUG2, "in: create_anon_mem_cfl\n"); if (D > DIMS_MAX) { BART_WARN("create_anon_mem_cfl: D > DIMS_MAX: %d > %d!\n", D, DIMS_MAX); } return mem_handler.allocate_mem_cfl(D, const_cast(dims)); } void* load_mem_cfl(const char* name, unsigned int D, long dims[]) { debug_printf(DP_DEBUG2, "in: load_mem_cfl\n"); if (D > DIMS_MAX) { BART_WARN("load_mem_cfl: D > DIMS_MAX: %d > %d!\n", D, DIMS_MAX); } cx_float* ret = mem_handler.load_mem_cfl(name, D, dims); return ret; } template void register_mem_cfl_impl(const char* name, unsigned int D, const long dims[], void* data) { if (D > DIMS_MAX) { BART_WARN("register_mem_cfl_impl: D > DIMS_MAX: %d > %d!\n", D, DIMS_MAX); } mem_handler.register_mem_cfl(name, D, const_cast(dims), reinterpret_cast(data), deleter_t()); } void register_mem_cfl_non_managed(const char* name, unsigned int D, const long dims[], void* data) { debug_printf(DP_DEBUG2, "in: register_mem_cfl_non_managed\n"); /* NB: due to the use of noop_delete, the memory will not be freed upon * destruction */ register_mem_cfl_impl(name, D, dims, data); } void register_mem_cfl_malloc(const char* name, unsigned int D, const long dims[], void* data) { debug_printf(DP_DEBUG2, "in: register_mem_cfl_malloc\n"); register_mem_cfl_impl(name, D, dims, data); } void register_mem_cfl_new(const char* name, unsigned int D, const long dims[], void* data) { debug_printf(DP_DEBUG2, "in: register_mem_cfl_new\n"); register_mem_cfl_impl(name, D, dims, data); } _Bool is_mem_cfl(const cx_float* ptr) { return mem_handler.is_mem_cfl(ptr); } _Bool try_delete_mem_cfl(const cx_float* ptr) { return mem_handler.try_delete_mem_cfl(ptr); } _Bool deallocate_mem_cfl_name(const char* name) { return mem_handler.remove(name); } _Bool deallocate_mem_cfl_ptr(const cx_float* ptr) { return mem_handler.remove(ptr); } void deallocate_all_mem_cfl() { debug_printf(DP_DEBUG2, "in: deallocate_all_mem_cfl\n"); mem_handler.clear(); } // ============================================================================= #ifdef BART_WITH_PYTHON bool register_mem_cfl_python(const char* name, const numpy_farray_t& array) { debug_printf(DP_DEBUG2, "in: register_mem_cfl_python\n"); if (array.ndim() > DIMS_MAX) { BART_WARN("register_mem_cfl_python: D > DIMS_MAX: %d > %d!\n", array.ndim(), DIMS_MAX); } // This call may throw! mem_handler.register_mem_cfl(name, array); return true; } #endif /* BART_WITH_PYTHON */ bart-0.5.00/src/misc/mmiocc.hh000066400000000000000000000026301353046746100160500ustar00rootroot00000000000000/* Copyright 2017-2018. Damien Nguyen. * Copyright 2017-2018. Francesco Santini * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Damien Nguyen * 2017-2018 Francesco Santini */ #include "misc/cppwrap.h" extern void* create_mem_cfl(const char* name, unsigned int D, const long dimensions[]); extern void* create_anon_mem_cfl(unsigned int D, const long dimensions[]); extern void* load_mem_cfl(const char* name, unsigned int D, long dimensions[]); extern void register_mem_cfl_non_managed(const char* name, unsigned int D, const long dims[], void* data); // Note: for both function below, the internal memory handler takes ownership of the data! (ie. will get automatically deallocated) extern void register_mem_cfl_malloc(const char* name, unsigned int D, const long dimensions[], void* data); extern void register_mem_cfl_new(const char* name, unsigned int D, const long dimensions[], void* data); extern _Bool is_mem_cfl(const _Complex float* ptr); // Try to delete an entry from the list of memory CFL files. extern _Bool try_delete_mem_cfl(const _Complex float* ptr); extern _Bool deallocate_mem_cfl_name(const char* name); extern _Bool deallocate_mem_cfl_ptr(const _Complex float* ptr); extern void deallocate_all_mem_cfl(); #include "misc/cppwrap.h" bart-0.5.00/src/misc/mri.c000066400000000000000000000133311353046746100152130ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/loop.h" #include "misc/misc.h" #include "misc/debug.h" #include "sense/optcom.h" #include "mri.h" void data_consistency(const long dims[DIMS], complex float* dst, const complex float* pattern, const complex float* kspace1, const complex float* kspace2) { assert(1 == dims[MAPS_DIM]); long strs[DIMS]; long dims1[DIMS]; long strs1[DIMS]; md_select_dims(DIMS, ~COIL_FLAG, dims1, dims); md_calc_strides(DIMS, strs1, dims1, CFL_SIZE); md_calc_strides(DIMS, strs, dims, CFL_SIZE); complex float* tmp = md_alloc_sameplace(DIMS, dims, CFL_SIZE, dst); md_zmul2(DIMS, dims, strs, tmp, strs, kspace2, strs1, pattern); md_zsub(DIMS, dims, tmp, kspace2, tmp); md_zfmac2(DIMS, dims, strs, tmp, strs, kspace1, strs1, pattern); md_copy(DIMS, dims, dst, tmp, CFL_SIZE); md_free(tmp); } void estimate_pattern(unsigned int D, const long dims[D], unsigned int flags, complex float* pattern, const complex float* kspace_data) { md_zrss(D, dims, flags, pattern, kspace_data); long dims2[D]; long strs2[D]; md_select_dims(D, ~flags, dims2, dims); md_calc_strides(D, strs2, dims2, CFL_SIZE); long strs1[D]; md_singleton_strides(D, strs1); md_zcmp2(D, dims2, strs2, pattern, strs2, pattern, strs1, &(complex float){ 0. }); md_zsub2(D, dims2, strs2, pattern, strs1, &(complex float){ 1. }, strs2, pattern); } static void calib_readout_pos(const long caldims[DIMS], long calpos[DIMS], const long in_dims[DIMS], const complex float* in_data) { // now move along readout to find maximum energy long in_strs[DIMS]; md_calc_strides(DIMS, in_strs, in_dims, CFL_SIZE); int maxind = 0; float maxeng = 0.; for (int r = 0; r < in_dims[READ_DIM] - caldims[READ_DIM] + 1; r++) { calpos[READ_DIM] = r; long offset = md_calc_offset(DIMS, calpos, in_strs); float energy = md_znorm2(DIMS, caldims, in_strs, in_data + offset / CFL_SIZE); if (energy > maxeng) { maxind = r; maxeng = energy; } } calpos[READ_DIM] = maxind; } void calib_geom(long caldims[DIMS], long calpos[DIMS], const long calsize[3], const long in_dims[DIMS], const complex float* in_data) { long pat_dims[DIMS]; assert(1 == in_dims[MAPS_DIM]); md_select_dims(DIMS, ~COIL_FLAG, pat_dims, in_dims); complex float* pattern = md_alloc(DIMS, pat_dims, CFL_SIZE); estimate_pattern(DIMS, in_dims, COIL_FLAG, pattern, in_data); for (unsigned int i = 0; i < DIMS; i++) caldims[i] = 1; for (unsigned int i = 0; i < DIMS; i++) calpos[i] = 0; calpos[0] = (in_dims[0] - caldims[0]) / 2; calpos[1] = (in_dims[1] - caldims[1]) / 2; calpos[2] = (in_dims[2] - caldims[2]) / 2; long pat_strs[DIMS]; md_calc_strides(DIMS, pat_strs, pat_dims, CFL_SIZE); bool stop[3] = { false, false, false }; // increase in diagonals first while (!(stop[0] && stop[1] & stop[2])) { for (int i = 0; i < 3; i++) { if (caldims[i] == in_dims[i]) stop[i] = true; if (caldims[i] >= calsize[i]) stop[i] = true; if (stop[i]) continue; caldims[i] += 1; calpos[i] = (in_dims[i] - caldims[i]) / 2; // printf("Try: %ld %ld %ld %ld\n", caldims[1], caldims[2], calpos[1], calpos[2]); long offset = md_calc_offset(DIMS, calpos, pat_strs); float si = sqrtf((float)caldims[0] * (float)caldims[1] * (float)caldims[2]); if (si != md_znorm2(DIMS, caldims, pat_strs, pattern + offset / CFL_SIZE)) { caldims[i]--; calpos[i] = (in_dims[i] - caldims[i]) / 2; stop[i] = true; } } } caldims[COIL_DIM] = in_dims[COIL_DIM]; md_free(pattern); #if 1 calib_readout_pos(caldims, calpos, in_dims, in_data); #endif } complex float* extract_calib2(long caldims[DIMS], const long calsize[3], const long in_dims[DIMS], const long in_strs[DIMS], const complex float* in_data, bool fixed) { // first extract center of size in_dims[0], calsize[1], calsize[2], and then process further to save time long tmp_dims[DIMS]; long tmp_pos[DIMS]; long tmp_strs[DIMS]; md_copy_dims(DIMS, tmp_dims, in_dims); md_set_dims(DIMS, tmp_pos, 0); for (unsigned int i = 0; i < 3; i++) { //tmp_dims[i] = MIN(calsize[i], in_dims[i]); tmp_dims[i] = (READ_DIM == i) ? in_dims[i] : MIN(calsize[i], in_dims[i]); tmp_pos[i] = (in_dims[i] - tmp_dims[i]) / 2.; // what about odd sizes? } complex float* tmp_data = md_alloc(DIMS, tmp_dims, CFL_SIZE); md_calc_strides(DIMS, tmp_strs, tmp_dims, CFL_SIZE); md_copy_block2(DIMS, tmp_pos, tmp_dims, tmp_strs, tmp_data, in_dims, in_strs, in_data, CFL_SIZE); long calpos[DIMS]; calib_geom(caldims, calpos, calsize, tmp_dims, tmp_data); if (fixed) { // we should probably change calib_geom instead for (unsigned int i = 0; i < 3; i++) { caldims[i] = MIN(calsize[i], tmp_dims[i]); if (i != READ_DIM) calpos[i] = (tmp_dims[i] - caldims[i]) / 2; } } debug_printf(DP_DEBUG1, "Calibration region... (size: %ldx%ldx%ld, pos: %ldx%ldx%ld)\n", caldims[0], caldims[1], caldims[2], calpos[0] + tmp_pos[0], calpos[1] + tmp_pos[1], calpos[2] + tmp_pos[2]); complex float* cal_data = md_alloc(DIMS, caldims, CFL_SIZE); md_copy_block(DIMS, calpos, caldims, cal_data, tmp_dims, tmp_data, CFL_SIZE); md_free(tmp_data); return cal_data; } complex float* extract_calib(long caldims[DIMS], const long calsize[3], const long in_dims[DIMS], const complex float* in_data, bool fixed) { long in_strs[DIMS]; md_calc_strides(DIMS, in_strs, in_dims, CFL_SIZE); return extract_calib2(caldims, calsize, in_dims, in_strs, in_data, fixed); } bart-0.5.00/src/misc/mri.h000066400000000000000000000037151353046746100152250ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __MRI_H #define __MRI_H #include #include "misc/cppwrap.h" enum mri_dims { READ_DIM, PHS1_DIM, PHS2_DIM, COIL_DIM, MAPS_DIM, TE_DIM, COEFF_DIM, COEFF2_DIM, ITER_DIM, CSHIFT_DIM, TIME_DIM, TIME2_DIM, LEVEL_DIM, SLICE_DIM, AVG_DIM, }; #ifdef BERKELEY_SVN #define KSPACE_DIMS 16u #endif #ifndef DIMS #define DIMS 16u #endif #define READ_FLAG (1u << READ_DIM) #define PHS1_FLAG (1u << PHS1_DIM) #define PHS2_FLAG (1u << PHS2_DIM) #define COIL_FLAG (1u << COIL_DIM) #define MAPS_FLAG (1u << MAPS_DIM) #define TE_FLAG (1u << TE_DIM) #define COEFF_FLAG (1u << COEFF_DIM) #define COEFF2_FLAG (1u << COEFF2_DIM) #define ITER_FLAG (1u << ITER_DIM) #define CSHIFT_FLAG (1u << CSHIFT_DIM) #define TIME_FLAG (1u << TIME_DIM) #define TIME2_FLAG (1u << TIME2_DIM) #define LEVEL_FLAG (1u << LEVEL_DIM) #define FFT_FLAGS (READ_FLAG|PHS1_FLAG|PHS2_FLAG) #define SENS_FLAGS (COIL_FLAG|MAPS_FLAG) #define SLICE_FLAG (1u << SLICE_DIM) extern void estimate_pattern(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* pattern, const _Complex float* kspace_data); extern _Complex float* extract_calib(long caldims[DIMS], const long calsize[3], const long in_dims[DIMS], const _Complex float* in_data, _Bool fixed); extern _Complex float* extract_calib2(long caldims[DIMS], const long calsize[3], const long in_dims[DIMS], const long in_strs[DIMS], const _Complex float* in_data, _Bool fixed); extern void data_consistency(const long dims[DIMS], _Complex float* dst, const _Complex float* pattern, const _Complex float* kspace1, const _Complex float* kspace2); extern void calib_geom(long caldims[DIMS], long calpos[DIMS], const long calsize[3], const long in_dims[DIMS], const _Complex float* in_data); #include "misc/cppwrap.h" #endif // __MRI_H bart-0.5.00/src/misc/nested.h000066400000000000000000000024561353046746100157210ustar00rootroot00000000000000 #if defined(__clang__) && !defined(__CUDACC__) #define NESTED(RET, NAME, ARGS) \ RET (^NAME)ARGS = ^ARGS #define CLOSURE_TYPE(x) (^x) #else #define NESTED(RET, NAME, ARGS) \ RET NAME ARGS #define CLOSURE_TYPE(x) x #define __block #endif #if defined(__clang__) || !defined(NOEXEC_STACK) #define NESTED_CALL(x, args) ((x)args) #else #ifndef __x86_64__ #error NOEXEC_STACK only supported on x86_64 #endif #include #if __GNUC__ >= 10 #define NESTED_CALL(p, args) ({ \ __auto_type __p = (p); \ struct { unsigned short mov1; unsigned int addr; unsigned short mov2; void* chain; unsigned int jmp; } \ __attribute__((packed))* __t = (void*)p; \ assert((0xbb41 == __t->mov1) && (0xba49 == __t->mov2) && (0x90e3ff49 == __t->jmp)); \ __builtin_call_with_static_chain(((__typeof__(__p))((unsigned long)__t->addr))args, (void*)__t->chain); \ }) #else #define NESTED_CALL(p, args) ({ \ __auto_type __p = (p); \ struct { unsigned short mov1; void* addr; unsigned short mov2; void* chain; unsigned int jmp; } \ __attribute__((packed))* __t = (void*)p; \ assert((0xbb49 == __t->mov1) && (0xba49 == __t->mov2) && (0x90e3ff49 == __t->jmp)); \ __builtin_call_with_static_chain(((__typeof__(__p))(__t->addr))args, __t->chain); \ }) #endif #endif bart-0.5.00/src/misc/opts.c000066400000000000000000000164321353046746100154160ustar00rootroot00000000000000/* Copyright 2015-2017. Martin Uecker. * Copyright 2017-2018. Damien Nguyen. * Copyright 2017-2018. Francesco Santini. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015-2017 Martin Uecker * 2017-2018 Nguyen Damien * 2017-2018 Francesco Santini */ #define _GNU_SOURCE #include "ya_getopt.h" #include #include #include #include #include #include #include "misc/misc.h" #include "misc/debug.h" #include "opts.h" enum OPT_ARG_TYPE { OPT_SPECIAL, OPT_SET, OPT_CLEAR, OPT_INT, OPT_UINT, OPT_LONG, OPT_FLOAT, OPT_STRING }; static const char* opt_arg_types[] = { " ...", "", "", " d", " d", " d", " f", " " }; static enum OPT_ARG_TYPE opt_arg_type(opt_conv_f fun) { if (opt_set == fun) return OPT_SET; if (opt_clear == fun) return OPT_CLEAR; if (opt_int == fun) return OPT_INT; if (opt_uint == fun) return OPT_UINT; if (opt_long == fun) return OPT_LONG; if (opt_float == fun) return OPT_FLOAT; if (opt_string == fun) return OPT_STRING; return OPT_SPECIAL; } static const char* trim_space(const char* str) { while (isspace(*str)) str++; return str; } static bool show_option_p(const struct opt_s opt) { return (NULL != opt.descr) && !( ('(' == trim_space(opt.descr)[0]) && (')' == opt.descr[strlen(opt.descr) - 1])); } static void print_usage(FILE* fp, const char* name, const char* usage_str, int n, const struct opt_s opts[static n ?: 1]) { fprintf(fp, "Usage: %s ", name); for (int i = 0; i < n; i++) if (show_option_p(opts[i])) fprintf(fp, "[-%c%s] ", opts[i].c, opt_arg_types[opt_arg_type(opts[i].conv)]); fprintf(fp, "%s\n", usage_str); } static const char* add_space(bool has_arg, bool has_space) { const char* space = "\t\t"; if (has_arg) space = " "; if (!has_space) space = ""; return space; } static void print_help(const char* help_str, int n, const struct opt_s opts[n ?: 1]) { printf("\n%s\n\n", help_str); for (int i = 0; i < n; i++) if (show_option_p(opts[i])) printf("-%c%s%s\n", opts[i].c, add_space(opts[i].arg, isspace(opts[i].descr[0])), trim_space(opts[i].descr)); printf("-h\t\thelp\n"); } static void check_options(int n, const struct opt_s opts[n ?: 1]) { bool f[256] = { false }; for (int i = 0; i < n; i++) { assert(256 > (unsigned int)opts[i].c); if (f[(unsigned int)opts[i].c]) error("duplicate option: %c\n", opts[i].c); f[(unsigned int)opts[i].c] = true; } } static void process_option(char c, const char* optarg, const char* name, const char* usage_str, const char* help_str, int n, const struct opt_s opts[n ?: 1]) { if ('h' == c) { print_usage(stdout, name, usage_str, n, opts); print_help(help_str, n, opts); exit(0); } for (int i = 0; i < n; i++) { if (opts[i].c == c) { if (opts[i].conv(opts[i].ptr, c, optarg)) { print_usage(stderr, name, usage_str, n, opts); error("process_option: failed to convert value\n"); } return; } } print_usage(stderr, name, usage_str, n, opts); error("process_option: unknown option\n"); } void cmdline(int* argcp, char* argv[], int min_args, int max_args, const char* usage_str, const char* help_str, int n, const struct opt_s opts[n ?: 1]) { int argc = *argcp; char optstr[2 * n + 2]; getopt_reset(); // reset getopt variables to process multiple argc/argv pairs check_options(n, opts); save_command_line(argc, argv); int l = 0; optstr[l++] = 'h'; for (int i = 0; i < n; i++) { optstr[l++] = opts[i].c; if (opts[i].arg) optstr[l++] = ':'; } optstr[l] = '\0'; int c; while (-1 != (c = getopt(argc, argv, optstr))) { #if 0 if ('h' == c) { print_usage(stdout, argv[0], usage_str, n, opts); print_help(help_str, n, opts); exit(0); } for (int i = 0; i < n; i++) { if (opts[i].c == c) { if (opts[i].conv(opts[i].ptr, c, optarg)) { print_usage(stderr, argv[0], usage_str, n, opts); error("cmdline: failed to convert value\n"); } goto out; } } print_usage(stderr, argv[0], usage_str, n, opts); exit(1); out: continue; #else process_option(c, optarg, argv[0], usage_str, help_str, n, opts); #endif } if ( (argc - optind < min_args) || (argc - optind > max_args)) { print_usage(stderr, argv[0], usage_str, n, opts); error("cmdline: too few or too many arguments\n"); } int i; for (i = optind; i < argc; i++) argv[i - optind + 1] = argv[i]; *argcp = argc - optind + 1; } bool opt_set(void* ptr, char c, const char* optarg) { UNUSED(c); UNUSED(optarg); *(bool*)ptr = true; return false; } bool opt_clear(void* ptr, char c, const char* optarg) { UNUSED(c); UNUSED(optarg); *(bool*)ptr = false; return false; } bool opt_int(void* ptr, char c, const char* optarg) { UNUSED(c); *(int*)ptr = atoi(optarg); return false; } bool opt_uint(void* ptr, char c, const char* optarg) { UNUSED(c); *(unsigned int*)ptr = atoi(optarg); return false; } bool opt_long(void* ptr, char c, const char* optarg) { UNUSED(c); *(long*)ptr = atoi(optarg); return false; } bool opt_float(void* ptr, char c, const char* optarg) { UNUSED(c); *(float*)ptr = atof(optarg); return false; } bool opt_string(void* ptr, char c, const char* optarg) { UNUSED(c); *(char**)ptr = strdup(optarg); assert(NULL != ptr); return false; } bool opt_float_vec2(void* ptr, char c, const char* optarg) { UNUSED(c); int r = sscanf(optarg, "%f:%f", &(*(float(*)[2])ptr)[0], &(*(float(*)[2])ptr)[1]); assert(2 == r); return false; } bool opt_vec2(void* ptr, char c, const char* optarg) { if (islower(c)) { if (2 != sscanf(optarg, "%ld:%ld", &(*(long(*)[2])ptr)[0], &(*(long(*)[2])ptr)[1])) { (*(long(*)[3])ptr)[0] = atol(optarg); (*(long(*)[3])ptr)[1] = atol(optarg); } } else { debug_printf(DP_WARN, "the upper-case options for specifying dimensions are deprecated.\n"); int r = sscanf(optarg, "%ld:%ld", &(*(long(*)[2])ptr)[0], &(*(long(*)[2])ptr)[1]); assert(2 == r); } return false; } bool opt_float_vec3(void* ptr, char c, const char* optarg) { UNUSED(c); int r = sscanf(optarg, "%f:%f:%f", &(*(float(*)[3])ptr)[0], &(*(float(*)[3])ptr)[1], &(*(float(*)[3])ptr)[2]); assert(3 == r); return false; } bool opt_vec3(void* ptr, char c, const char* optarg) { if (islower(c)) { if (3 != sscanf(optarg, "%ld:%ld:%ld", &(*(long(*)[3])ptr)[0], &(*(long(*)[3])ptr)[1], &(*(long(*)[3])ptr)[2])) { (*(long(*)[3])ptr)[0] = atol(optarg); (*(long(*)[3])ptr)[1] = atol(optarg); (*(long(*)[3])ptr)[2] = atol(optarg); } } else { debug_printf(DP_WARN, "the upper-case options for specifying dimensions are deprecated.\n"); int r = sscanf(optarg, "%ld:%ld:%ld", &(*(long(*)[3])ptr)[0], &(*(long(*)[3])ptr)[1], &(*(long(*)[3])ptr)[2]); assert(3 == r); } return false; } bool opt_select(void* ptr, char c, const char* optarg) { UNUSED(c); UNUSED(optarg); struct opt_select_s* sel = ptr; if (0 != memcmp(sel->ptr, sel->default_value, sel->size)) return true; memcpy(sel->ptr, sel->value, sel->size); return false; } bool opt_subopt(void* _ptr, char c, const char* optarg) { UNUSED(c); struct opt_subopt_s* ptr = _ptr; process_option(optarg[0], optarg + 1, "", "", "", ptr->n, ptr->opts); return false; } bart-0.5.00/src/misc/opts.h000066400000000000000000000051671353046746100154260ustar00rootroot00000000000000 #include #include "misc/cppwrap.h" #include "misc/types.h" #include "misc/misc.h" typedef bool opt_conv_f(void* ptr, char c, const char* optarg); struct opt_s { char c; bool arg; opt_conv_f* conv; void* ptr; const char* descr; }; extern opt_conv_f opt_set; extern opt_conv_f opt_clear; extern opt_conv_f opt_int; extern opt_conv_f opt_uint; extern opt_conv_f opt_long; extern opt_conv_f opt_float; extern opt_conv_f opt_string; extern opt_conv_f opt_vec2; extern opt_conv_f opt_float_vec2; extern opt_conv_f opt_vec3; extern opt_conv_f opt_float_vec3; extern opt_conv_f opt_select; extern opt_conv_f opt_subopt; struct opt_select_s { void* ptr; const void* value; const void* default_value; size_t size; }; struct opt_subopt_s { int n; struct opt_s* opts; }; typedef long opt_vec2_t[2]; typedef float opt_fvec2_t[2]; typedef long opt_vec3_t[3]; typedef float opt_fvec3_t[3]; #define OPT_SEL(T, x, v) &(struct opt_select_s){ (x), &(T){ (v) }, &(T){ *(x) }, sizeof(T) } #define OPT_SUB(n, opts) &(struct opt_subopt_s){ (n), (opts) } #define OPT_SET(c, ptr, descr) { (c), false, opt_set, TYPE_CHECK(bool*, (ptr)), "\t" descr } #define OPT_CLEAR(c, ptr, descr) { (c), false, opt_clear, TYPE_CHECK(bool*, (ptr)), "\t" descr } #define OPT_ARG(c, _fun, T, ptr, argname, descr) { (c), true, _fun, TYPE_CHECK(T*, (ptr)), " " argname " \t" descr } #define OPT_STRING(c, ptr, argname, descr) OPT_ARG(c, opt_string, const char*, ptr, argname, descr) #define OPT_UINT(c, ptr, argname, descr) OPT_ARG(c, opt_uint, unsigned int, ptr, argname, descr) #define OPT_INT(c, ptr, argname, descr) OPT_ARG(c, opt_int, int, ptr, argname, descr) #define OPT_LONG(c, ptr, argname, descr) OPT_ARG(c, opt_long, long, ptr, argname, descr) #define OPT_FLOAT(c, ptr, argname, descr) OPT_ARG(c, opt_float, float, ptr, argname, descr) #define OPT_VEC2(c, ptr, argname, descr) OPT_ARG(c, opt_vec2, opt_vec2_t, ptr, argname, descr) #define OPT_FLVEC2(c, ptr, argname, descr) OPT_ARG(c, opt_float_vec2, opt_fvec2_t, ptr, argname, descr) #define OPT_VEC3(c, ptr, argname, descr) OPT_ARG(c, opt_vec3, opt_vec3_t, ptr, argname, descr) #define OPT_FLVEC3(c, ptr, argname, descr) OPT_ARG(c, opt_float_vec3, opt_fvec3_t, ptr, argname, descr) #define OPT_SELECT(c, T, ptr, value, descr) { (c), false, opt_select, OPT_SEL(T, TYPE_CHECK(T*, ptr), value), "\t" descr } #define OPT_SUBOPT(c, argname, descr, NR, opts) OPT_ARG(c, opt_subopt, struct opt_subopt_s, OPT_SUB(NR, opts), argname, descr) extern void cmdline(int* argc, char* argv[], int min_args, int max_args, const char* usage_str, const char* help_str, int n, const struct opt_s opts[n]); #include "misc/cppwrap.h" bart-0.5.00/src/misc/pd.c000066400000000000000000000155231353046746100150340ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker * * Wei, L. Multi-Class Blue Noise Sampling. ACM Trans. Graph. 29:79 (2010) * */ #include #include #include #include #if 1 #define GRID // #define CHECK #endif #ifdef GRID #include "num/multind.h" #endif #include "num/rand.h" #include "misc/misc.h" #include "pd.h" static float dist(int D, const float a[D], const float b[D]) { float r = 0.; for (int i = 0; i < D; i++) r += powf(a[i] - b[i], 2.); return sqrtf(r); } #ifdef GRID static void grid_pos(int D, long pos[D], float delta, const float fpos[D]) { for (int i = 0; i < D; i++) pos[i] = (int)floorf(fpos[i] / delta); } #endif static float vard_scale(int D, const float p[D], float vard) { float cen[D]; for (int i = 0; i < D; i++) cen[i] = 0.5; return 1. + powf(dist(D, cen, p), 2.) * vard; } static bool distance_check(int D, int T, int N, float vard, const float delta[T][T], /*const*/ float points[N][D], const int kind[N], int a, int b) { return dist(D, points[a], points[b]) > vard_scale(D, points[a], vard) * delta[kind[a]][kind[b]]; } int (poissondisc_mc)(int D, int T, int N, int I, float vardens, const float delta[T][T], float points[N][D], int kind[N]) { PTR_ALLOC(char[N], active); assert((0 < I) && (I < N)); assert(vardens >= 0.); // otherwise grid granularity needs to be changed memset(*active, 0, N * sizeof(char)); memset(*active, 1, I * sizeof(char)); int k = 30; int p = I; int a = I; #ifdef GRID float mindelta = 1.; float maxdelta = 0.; for (int i = 0; i < T; i++) { for (int j = 0; j < T; j++) { if (delta[i][j] < mindelta) mindelta = delta[i][j]; if (delta[i][j] > maxdelta) maxdelta = delta[i][j]; } } float corner[D]; for (int i = 0; i < D; i++) corner[i] = 0.; maxdelta *= vard_scale(D, corner, vardens); mindelta /= sqrtf((float)D); long patchdims[D]; for (int i = 0; i < D; i++) patchdims[i] = 3 * ceilf(maxdelta / mindelta); long patchstrs[D]; md_calc_strides(D, patchstrs, patchdims, 1); int* patch = md_alloc(D, patchdims, sizeof(int)); long griddims[D]; for (int i = 0; i < D; i++) griddims[i] = ceilf(1. / mindelta); long gridstrs[D]; md_calc_strides(D, gridstrs, griddims, 1); // element size 1! int* grid = md_alloc(D, griddims, sizeof(int)); int mone = -1; md_fill(D, griddims, grid, &mone, sizeof(int)); for (int i = 0; i < I; i++) { long pos[D]; grid_pos(D, pos, mindelta, points[i]); grid[md_calc_offset(D, gridstrs, pos)] = i; } #endif while (a > 0) { // pick active point randomly int sel = (int)floor(a * uniform_rand()) % a; int s2 = 0; while (true) { while (!(*active)[s2]) s2++; if (0 == sel) break; sel--; s2++; } assert((*active)[s2]); // try k times to place a new point near the selected point bool found = false; int rr = 0; // ? for (int i = 0; i < k; i++) { float d; float dd; // create a random point between one and two times the allowed distance do { kind[p] = rr++ % T; dd = delta[kind[s2]][kind[p]]; dd *= vard_scale(D, points[s2], vardens); for (int j = 0; j < D; j++) { do { points[p][j] = points[s2][j] + (uniform_rand() - 0.5) * 4. * dd; } while ((points[p][j] < 0.) || (points[p][j] > 1.)); } d = dist(D, points[s2], points[p]); } while ((d < dd) || (d > 2. * dd)); // check if the new point is far enough from all other points bool accept = true; #ifdef GRID long pos[D]; grid_pos(D, pos, mindelta, points[p]); long index = md_calc_offset(D, gridstrs, pos); assert(index < md_calc_size(D, griddims)); if (-1 != grid[index]) { assert(!distance_check(D, T, N, vardens, delta, points, kind, p, grid[index])); accept = false; } if (accept) { long off[D]; for (int i = 0; i < D; i++) off[i] = MIN(MAX(0, pos[i] - (patchdims[i] + 1) / 2), griddims[i] - patchdims[i]); md_copy_block(D, off, patchdims, patch, griddims, grid, sizeof(int)); for (int i = 0; i < md_calc_size(D, patchdims); i++) if (-1 != patch[i]) accept &= distance_check(D, T, N, vardens, delta, points, kind, p, patch[i]); } #endif #ifdef CHECK bool accept2 = true; for (int j = 0; j < p; j++) accept2 &= distance_check(D, T, N, vardens, delta, points, kind, p, j); assert(accept == accept2); #endif #ifndef GRID for (int j = 0; j < p; j++) accept &= distance_check(D, T, N, vardens, delta, points, kind, p, j); #endif if (accept) { // add new point to active list #ifdef GRID assert(-1 == grid[index]); // 0 is actually the first point grid[index] = p; #endif (*active)[p] = 1; a++; p++; if (N == p) goto out; found = true; break; } } // if we can not place a new point, remove point from active list if (!found) { (*active)[s2] = 0; a--; } } out: #ifdef GRID md_free(grid); md_free(patch); #endif XFREE(active); return p; } extern int poissondisc(int D, int N, int I, float vardens, float delta, float points[N][D]) { PTR_ALLOC(int[N], kind); memset(*kind, 0, I * sizeof(int)); const float dd[1][1] = { { delta } }; int P = poissondisc_mc(D, 1, N, I, vardens, dd, points, *kind); XFREE(kind); return P; } static void compute_rmatrix(int D, int T, float rmatrix[T][T], const float delta[T], int C, const int nc[T], const int mc[T][T]) { unsigned long processed = 0; float density = 0.; for (int i = 0; i < T; i++) rmatrix[i][i] = delta[i]; for (int k = 0; k < C; k++) { for (int i = 0; i < nc[k]; i++) { int ind = mc[k][i]; processed = MD_SET(processed, ind); density += 1. / powf(delta[ind], (float)D); // printf("%d (%f)\t", ind, density); } //printf("\n"); for (int i = 0; i < nc[k]; i++) for (int j = 0; j < T; j++) if (MD_IS_SET(processed, j) && (i != j)) rmatrix[i][j] = rmatrix[j][i] = powf(density, -1. / (float)D); } } struct sort_label { int index; float x; }; static int sort_cmp(const void* _a, const void* _b) { const struct sort_label* a = _a; const struct sort_label* b = _b; return ((a->x < b->x) - (a->x > b->x)); // FIXME } extern void mc_poisson_rmatrix(int D, int T, float rmatrix[T][T], const float delta[T]) { assert(T <= 32); struct sort_label table[T]; for (int i = 0; i < T; i++) { table[i].index = i; table[i].x = delta[i]; } qsort(&table, T, sizeof(struct sort_label), sort_cmp); int mc[T][T]; int nc[T]; int ind = 0; int i; for (i = 0; (i < T) && (ind < T); i++) { float val = table[ind].x; int j = 0; while ((ind < T) && (table[ind].x == val)) mc[i][j++] = table[ind++].index; nc[i] = j; } compute_rmatrix(D, T, rmatrix, delta, i, nc, (const int (*)[T])mc); } bart-0.5.00/src/misc/pd.h000066400000000000000000000011531353046746100150330ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus #error This file does not support C++ #endif extern int poissondisc(int D, int N, int II, float vardens, float delta, float points[static N][D]); extern int poissondisc_mc(int D, int T, int N, int II, float vardens, const float delta[static T][T], float points[static N][D], int kind[static N]); extern void mc_poisson_rmatrix(int D, int T, float rmatrix[static T][T], const float delta[static T]); bart-0.5.00/src/misc/png.c000066400000000000000000000051151353046746100152110ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker */ #include #include #include #include #include "misc/misc.h" #include "png.h" static int png_write_anyrgb(const char* name, unsigned int w, unsigned int h, unsigned int nbytes, bool rgb, const unsigned char* buf) { FILE* fp; png_structp structp = NULL; png_infop infop = NULL; png_bytep* volatile row_ptrs = NULL; volatile int ret = -1; // default: return failure if (NULL == (fp = fopen(name, "wb"))) return -1; if (NULL == (structp = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto cleanup; if (NULL == (infop = png_create_info_struct(structp))) goto cleanup; if (setjmp(png_jmpbuf(structp))) goto cleanup; switch(nbytes){ case 3: png_set_IHDR(structp, infop, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); break; case 4: png_set_IHDR(structp, infop, w, h, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); break; default: error("Supported PNG formats are 24bit (RGB) and 32bit (RGBA)!\n"); } if (!rgb) png_set_bgr(structp); png_init_io(structp, fp); png_write_info(structp, infop); row_ptrs = xmalloc(sizeof(png_bytep) * h); int row_size = png_get_rowbytes(structp, infop); for (unsigned int i = 0; i < h; i++) row_ptrs[i] = (png_bytep)(buf + row_size * i); png_write_image(structp, row_ptrs); png_write_end(structp, infop); ret = 0; // return success cleanup: if (NULL != structp) png_destroy_write_struct(&structp, &infop); if (NULL != row_ptrs) xfree(row_ptrs); fclose(fp); return ret; } int png_write_rgb24(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf) { UNUSED(inum); return png_write_anyrgb(name, w, h, 3, true, buf); } int png_write_rgb32(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf) { UNUSED(inum); return png_write_anyrgb(name, w, h, 4, true, buf); } int png_write_bgr24(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf) { UNUSED(inum); return png_write_anyrgb(name, w, h, 3, false, buf); } int png_write_bgr32(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf) { UNUSED(inum); return png_write_anyrgb(name, w, h, 4, false, buf); } bart-0.5.00/src/misc/png.h000066400000000000000000000007161353046746100152200ustar00rootroot00000000000000 extern int png_write_rgb24(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf); extern int png_write_rgb32(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf); extern int png_write_bgr24(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf); extern int png_write_bgr32(const char* name, unsigned int w, unsigned int h, long inum, const unsigned char* buf); bart-0.5.00/src/misc/resize.c000066400000000000000000000146531353046746100157350ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2014 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/filter.h" #include "resize.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif // FIXME: implement inverse, adjoint, etc.. static void fft_xzeropad2(unsigned int N, const long dims[N], unsigned int d, unsigned int x, const long ostr[N], complex float* dst, const long istr[N], const complex float* src) { assert(d < N); long tdims[N + 1]; md_copy_dims(N, tdims, dims); tdims[N] = x; long tostr[N + 1]; md_copy_strides(N, tostr, ostr); tostr[d] = x * ostr[d]; tostr[N] = ostr[d]; long pdims[N + 1]; md_select_dims(N + 1, MD_BIT(d) | MD_BIT(N), pdims, tdims); long pstr[N + 1]; md_calc_strides(N + 1, pstr, pdims, CFL_SIZE); complex float* shift = md_alloc_sameplace(N + 1, pdims, CFL_SIZE, src); float pos[N]; for (unsigned int i = 0; i < N; i++) pos[i] = 0.; for (unsigned int i = 0; i < x; i++) { pos[d] = -(1. / (float)x) * i; linear_phase(N, pdims, pos, (void*)shift + i * pstr[N]); } long tistr[N + 1]; md_copy_strides(N, tistr, istr); tistr[N] = 0; md_zmul2(N + 1, tdims, tostr, dst, tistr, src, pstr, shift); md_free(shift); fftc2(N + 1, tdims, MD_BIT(d), tostr, dst, tostr, dst); } static void fft_xzeropad(unsigned int N, const long dims[N], unsigned int d, unsigned int x, complex float* dst, const complex float* src) { long odims[N]; long ostrs[N]; long istrs[N]; md_copy_dims(N, odims, dims); odims[d] = x * dims[d]; md_calc_strides(N, ostrs, odims, CFL_SIZE); md_calc_strides(N, istrs, dims, CFL_SIZE); fft_xzeropad2(N, dims, d, x, ostrs, dst, istrs, src); } static void fft_zeropad_simple(unsigned int N, unsigned int flags, const long odims[N], complex float* dst, const long idims[N], const complex float* src) { md_resize_center(N, odims, dst, idims, src, CFL_SIZE); fftc(N, odims, flags, dst, dst); } #if 0 static void fft_zeropad_simpleH(unsigned int N, unsigned int flags, const long odims[N], complex float* dst, const long idims[N], const complex float* src) { complex float* tmp = md_alloc_sameplace(N, idims, CFL_SIZE, src); ifftc(N, idims, flags, tmp, src); md_resize_center(N, odims, dst, idims, tmp, CFL_SIZE); md_free(tmp); } #endif static void fft_zeropad_r(unsigned int N, const long odims[N], complex float* dst, const long idims[N], const complex float* src) { int i = N - 1; while (odims[i] == idims[i]) { if (0 == i) { if (dst != src) md_copy(N, odims, dst, src, CFL_SIZE); return; } i--; } //printf("%d %ld %ld\n", i, odims[i], idims[i]); assert(odims[i] > idims[i]); long tdims[N]; md_copy_dims(N, tdims, idims); tdims[i] = odims[i]; complex float* tmp = md_alloc_sameplace(N, tdims, CFL_SIZE, src); #if 1 if (0 == tdims[i] % idims[i]) { fft_xzeropad(N, idims, i, tdims[i] / idims[i], tmp, src); } else { #else { #endif fft_zeropad_simple(N, MD_BIT(i), tdims, tmp, idims, src); } fft_zeropad_r(N, odims, dst, tdims, tmp); md_free(tmp); } /* * perform zero-padded FFT * */ void fft_zeropad(unsigned int N, unsigned int flags, const long odims[N], complex float* dst, const long idims[N], const complex float* src) { unsigned int lflags = 0; for (unsigned int i = 0; i < N; i++) if (odims[i] > idims[i]) lflags = MD_SET(lflags, i); assert(flags == lflags); unsigned int sflags = 0; for (unsigned int i = 0; i < N; i++) if (odims[i] < idims[i]) sflags = MD_SET(sflags, i); assert(0 == sflags); fft_zeropad_r(N, odims, dst, idims, src); } static void fft_zeropadH_r(unsigned int N, const long odims[N], complex float* dst, const long idims[N], const complex float* src) { int i = N - 1; while (odims[i] == idims[i]) { if (0 == i) { if (dst != src) md_copy(N, odims, dst, src, CFL_SIZE); return; } i--; } assert (idims[i] > odims[i]); long tdims[N]; md_copy_dims(N, tdims, odims); tdims[i] = idims[i]; complex float* tmp = md_alloc_sameplace(N, tdims, CFL_SIZE, src); fft_zeropadH_r(N, tdims, tmp, idims, src); ifftc(N, tdims, MD_BIT(i), tmp, tmp); md_resize_center(N, odims, dst, tdims, tmp, CFL_SIZE); md_free(tmp); } /* * perform zero-padded FFT * */ void fft_zeropadH(unsigned int N, unsigned int flags, const long odims[N], complex float* dst, const long idims[N], const complex float* src) { unsigned int lflags = 0; for (unsigned int i = 0; i < N; i++) if (odims[i] > idims[i]) lflags = MD_SET(lflags, i); assert(0 == lflags); unsigned int sflags = 0; for (unsigned int i = 0; i < N; i++) if (odims[i] < idims[i]) sflags = MD_SET(sflags, i); assert(flags == sflags); fft_zeropadH_r(N, odims, dst, idims, src); } /* scale using zero-padding in the Fourier domain * */ void sinc_resize(unsigned int D, const long out_dims[D], complex float* out, const long in_dims[D], const complex float* in) { complex float* tmp = md_alloc_sameplace(D, in_dims, CFL_SIZE, in); unsigned int flags = 0; for (unsigned int i = 0; i < D; i++) if (out_dims[i] != in_dims[i]) flags = MD_SET(flags, i); fftmod(D, in_dims, flags, tmp, in); fft(D, in_dims, flags, tmp, tmp); fftmod(D, in_dims, flags, tmp, tmp); // NOTE: the inner fftmod/ifftmod should cancel for N % 4 == 0 // and could be replaced by a sign change for N % 4 == 1 // md_resize_center can size up or down md_resize_center(D, out_dims, out, in_dims, tmp, CFL_SIZE); md_free(tmp); ifftmod(D, out_dims, flags, out, out); // see above ifft(D, out_dims, flags, out, out); ifftmod(D, out_dims, flags, out, out); } /* scale using zero-padding in the Fourier domain - scale each dimensions in sequence (faster) * */ void sinc_zeropad(unsigned int D, const long out_dims[D], complex float* out, const long in_dims[D], const complex float* in) { unsigned int i = D - 1; while (out_dims[i] == in_dims[i]) { if (0 == i) { if (out != in) md_copy(D, out_dims, out, in, CFL_SIZE); return; } i--; } assert(out_dims[i] > in_dims[i]); long tmp_dims[D]; for (unsigned int l = 0; l < D; l++) tmp_dims[l] = in_dims[l]; tmp_dims[i] = out_dims[i]; //printf("Resizing...%d: %ld->%ld\n", i, in_dims[i], tmp_dims[i]); sinc_resize(D, tmp_dims, out, in_dims, in); sinc_zeropad(D, out_dims, out, tmp_dims, out); } bart-0.5.00/src/misc/resize.h000066400000000000000000000015731353046746100157370ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" extern void sinc_resize(unsigned int D, const long out_dims[__VLA(D)], _Complex float* out, const long in_dims[__VLA(D)], const _Complex float* in); extern void sinc_zeropad(unsigned int D, const long out_dims[__VLA(D)], _Complex float* out, const long in_dims[__VLA(D)], const _Complex float* in); extern void fft_zeropad(unsigned int D, unsigned int flags, const long out_dims[__VLA(D)], _Complex float* out, const long in_dims[__VLA(D)], const _Complex float* in); extern void fft_zeropadH(unsigned int D, unsigned int flags, const long out_dims[__VLA(D)], _Complex float* out, const long in_dims[__VLA(D)], const _Complex float* in); #include "misc/cppwrap.h" bart-0.5.00/src/misc/shrdptr.c000066400000000000000000000026611353046746100161160ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include #include "misc/types.h" #include "shrdptr.h" void shared_obj_init(struct shared_obj_s* obj, void (*del)(const struct shared_obj_s* s)) { obj->refcount = 1; obj->del = del; } void shared_obj_ref(const struct shared_obj_s* obj) { ((struct shared_obj_s*)obj)->refcount++; } void shared_obj_unref(const struct shared_obj_s* obj) { ((struct shared_obj_s*)obj)->refcount--; } void shared_obj_destroy(const struct shared_obj_s* x) { if (1 > --(((struct shared_obj_s*)x)->refcount)) if (NULL != x->del) x->del(x); } void shared_ptr_init(struct shared_ptr_s* dst, void (*del)(const struct shared_ptr_s*)) { dst->next = dst->prev = dst; dst->del = del; } void shared_ptr_copy(struct shared_ptr_s* dst, struct shared_ptr_s* src) { dst->next = src; dst->prev = src->prev; src->prev->next = dst; src->prev = dst; dst->del = src->del; } static void shared_unlink(struct shared_ptr_s* data) { data->next->prev = data->prev; data->prev->next = data->next; } void shared_ptr_destroy(const struct shared_ptr_s* ptr) { if (ptr->next == ptr) { assert(ptr == ptr->prev); ptr->del(ptr); } else { shared_unlink(CAST_CONST(struct shared_ptr_s*, ptr)); } } bart-0.5.00/src/misc/shrdptr.h000066400000000000000000000021551353046746100161210ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #ifndef __SHRDPTR_H #define __SHRDPTR_H // to be included in pointed-to object struct shared_obj_s { void (*del)(const struct shared_obj_s* x); int refcount; }; extern void shared_obj_init(struct shared_obj_s* obj, void (*del)(const struct shared_obj_s* s)); extern void shared_obj_destroy(const struct shared_obj_s* x); extern void shared_obj_ref(const struct shared_obj_s*); extern void shared_obj_unref(const struct shared_obj_s*); // alternative: to be included in object with pointer struct shared_ptr_s { struct shared_ptr_s* next; struct shared_ptr_s* prev; void (*del)(const struct shared_ptr_s*); }; extern void shared_ptr_init(struct shared_ptr_s* dst, void (*del)(const struct shared_ptr_s* p)); extern void shared_ptr_copy(struct shared_ptr_s* dst, struct shared_ptr_s* src); extern void shared_ptr_destroy(const struct shared_ptr_s* ptr); #endif // __SHRDPTR_H bart-0.5.00/src/misc/subpixel.c000066400000000000000000000017701353046746100162630ustar00rootroot00000000000000 #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "misc/misc.h" #include "subpixel.h" void est_subpixel_shift(unsigned int N, float shifts[N], const long dims[N], unsigned int flags, const complex float* in1, const complex float* in2) { complex float* tmp1 = md_alloc(N, dims, CFL_SIZE); complex float* tmp2 = md_alloc(N, dims, CFL_SIZE); fftuc(N, dims, flags, tmp1, in1); fftuc(N, dims, flags, tmp2, in2); md_zmulc(N, dims, tmp1, tmp1, tmp2); for (unsigned int i = 0; i < N; i++) { shifts[i] = 0.; if (!MD_IS_SET(flags, i)) continue; long shift[N]; for (unsigned int j = 0; j < N; j++) shift[j] = 0; shift[i] = 1; md_circ_shift(N, dims, shift, tmp2, tmp1, CFL_SIZE); // the weighting is not optimal due to double squaring // and we compute finite differences (filter?) complex float sc = md_zscalar(N, dims, tmp2, tmp1); shifts[i] = cargf(sc) / (2. * M_PI) * (float)dims[i]; } md_free(tmp1); md_free(tmp2); } bart-0.5.00/src/misc/subpixel.h000066400000000000000000000002371353046746100162650ustar00rootroot00000000000000 extern void est_subpixel_shift(unsigned int N, float shifts[N], const long dims[N], unsigned int flags, const complex float* in1, const complex float* in2); bart-0.5.00/src/misc/types.h000066400000000000000000000032051353046746100155740ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #ifndef __TYPES_H #define __TYPES_H #include #include #ifndef __cplusplus extern noreturn void error(const char* str, ...); #else extern __attribute__((noreturn)) void error(const char* str, ...); #endif #define TYPE_CHECK(T, x) (1 ? (x) : (T)0) #define CONTAINER_OF(x, T, member) \ ((T*)((char*)TYPE_CHECK(__typeof__(&((T*)0)->member), x) - offsetof(T, member))) #define CAST_CONST(T, x) ((T)TYPE_CHECK(const T, x)) #define CAST_MAYBE(T, x) ({ \ __typeof__(x) __tmp = (x); \ extern __typeof__(*__tmp->TYPEID) T ## _TYPEID; \ (__tmp->TYPEID == &T ## _TYPEID) ? \ CONTAINER_OF(__tmp, struct T, INTERFACE)\ : NULL; \ }) #define CAST_DOWN(T, x) ({ \ __typeof__(x) __tmp = (x); \ extern __typeof__(*__tmp->TYPEID) T ## _TYPEID; \ if (__tmp->TYPEID != &T ## _TYPEID) \ error("%s:%d run-time type check failed: %s\n", __FILE__, __LINE__, #T); \ CONTAINER_OF(__tmp, struct T, INTERFACE); \ }) #define CAST_UP(x) (&(x)->INTERFACE) #define INTERFACE(X) X INTERFACE typedef const struct typeid_s { int size; } TYPEID; #define TYPEID2(T) (T ## _TYPEID) #define TYPEID(T) (*({ extern TYPEID T ## _TYPEID; &T ## _TYPEID; })) #define DEF_TYPEID(T) TYPEID T ## _TYPEID = { sizeof(struct T) }; #define SET_TYPEID(T, x) (TYPE_CHECK(struct T*, x)->INTERFACE.TYPEID = &TYPEID(T)) #define SIZEOF(x) ((x)->TYPEID->size) // redefine auto - needs newer compilers #define auto __auto_type #endif bart-0.5.00/src/misc/utils.c000066400000000000000000000102431353046746100155630ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/loop.h" #include "misc/misc.h" #include "utils.h" complex float* compute_mask(unsigned int N, const long msk_dims[N], const float restrict_fov[N]) { complex float* mask = md_alloc(N, msk_dims, CFL_SIZE); long small_dims[N]; for (unsigned int i = 0; i < N; i++) small_dims[i] = (1 == msk_dims[i]) ? 1 : (msk_dims[i] * restrict_fov[i]); complex float* small_mask = md_alloc(N, small_dims, CFL_SIZE); md_fill(N, small_dims, small_mask, &(complex float){ 1. }, CFL_SIZE); md_resize_center(N, msk_dims, mask, small_dims, small_mask, CFL_SIZE); md_free(small_mask); return mask; } void apply_mask(unsigned int N, const long dims[N], complex float* x, const float restrict_fov[N]) { unsigned int flags = 0; for (unsigned int i = 0; i < N; i++) if (1. != restrict_fov[i]) flags = MD_SET(flags, i); long msk_dims[N]; md_select_dims(N, flags, msk_dims, dims); long msk_strs[N]; md_calc_strides(N, msk_strs, msk_dims, CFL_SIZE); complex float* mask = compute_mask(N, msk_dims, restrict_fov); long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); md_zmul2(N, dims, strs, x, strs, x, msk_strs, mask); md_free(mask); } void normalize(int N, unsigned int flags, const long dims[N], complex float* maps) { long dims_img[N]; md_select_dims(N, ~flags, dims_img, dims); complex float* maps_norm = md_alloc(N, dims_img, CFL_SIZE); md_zrss(N, dims, flags, maps_norm, maps); long str[N]; long str_img[N]; md_calc_strides(N, str, dims, CFL_SIZE); md_calc_strides(N, str_img, dims_img, CFL_SIZE); md_zdiv2(N, dims, str, maps, str, maps, str_img, maps_norm); md_free(maps_norm); } void normalizel1(int N, unsigned int flags, const long dims[N], complex float* maps) { long dims_img[N]; md_select_dims(N, ~flags, dims_img, dims); complex float* maps_norm = md_alloc(N, dims_img, CFL_SIZE); complex float* maps_abs = md_alloc(N, dims, CFL_SIZE); md_zabs(N, dims, maps_abs, maps); long strs[N]; long strs_img[N]; md_calc_strides(N, strs_img, dims_img, CFL_SIZE); md_calc_strides(N, strs, dims, CFL_SIZE); md_clear(N, dims_img, maps_norm, CFL_SIZE); md_zadd2(N, dims, strs_img, maps_norm, strs_img, maps_norm, strs, maps_abs); md_free(maps_abs); long str[N]; long str_img[N]; md_calc_strides(N, str, dims, CFL_SIZE); md_calc_strides(N, str_img, dims_img, CFL_SIZE); md_zdiv2(N, dims, str, maps, str, maps, str_img, maps_norm); md_free(maps_norm); } /* * rotate phase jointly along dim so that the 0-th slice along dim has phase = 0 * */ void fixphase(unsigned int N, const long dims[N], unsigned int dim, complex float* out, const complex float* in) { assert(dim < N); long dims2[N]; md_select_dims(N, ~MD_BIT(dim), dims2, dims); complex float* tmp = md_alloc_sameplace(N, dims2, CFL_SIZE, in); long pos[N]; for (unsigned int i = 0; i < N; i++) pos[i] = 0; md_slice(N, MD_BIT(dim), pos, dims, tmp, in, CFL_SIZE); md_zphsr(N, dims2, tmp, tmp); long strs[N]; long strs2[N]; md_calc_strides(N, strs, dims, CFL_SIZE); md_calc_strides(N, strs2, dims2, CFL_SIZE); md_zmulc2(N, dims, strs, out, strs, in, strs2, tmp); md_free(tmp); } void fixphase2(unsigned int N, const long dims[N], unsigned int dim, const complex float rot[dims[dim]], complex float* out, const complex float* in) { assert(dim < N); long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); long dims2[N]; long strs2[N]; md_select_dims(N, ~MD_BIT(dim), dims2, dims); md_calc_strides(N, strs2, dims2, CFL_SIZE); complex float* tmp = md_alloc_sameplace(N, dims2, CFL_SIZE, in); long tdims[N]; long tstrs[N]; md_select_dims(N, MD_BIT(dim), tdims, dims); md_calc_strides(N, tstrs, tdims, CFL_SIZE); md_clear(N, dims2, tmp, CFL_SIZE); md_zfmacc2(N, dims, strs2, tmp, strs, in, tstrs, rot); md_zphsr(N, dims2, tmp, tmp); md_zmulc2(N, dims, strs, out, strs, in, strs2, tmp); md_free(tmp); } bart-0.5.00/src/misc/utils.h000066400000000000000000000014451353046746100155740ustar00rootroot00000000000000 #include "misc/cppwrap.h" extern void normalizel1(int N, unsigned int flags, const long dims[__VLA(N)], _Complex float* maps); extern void normalize(int N, unsigned int flags, const long dims[__VLA(N)], _Complex float* maps); extern _Complex float* compute_mask(unsigned int N, const long msk_dims[__VLA(N)], const float restrict_fov[__VLA(N)]); extern void apply_mask(unsigned int N, const long dims[__VLA(N)], _Complex float* x, const float restrict_fov[__VLA(N)]); extern void fixphase(unsigned int D, const long dims[__VLA(D)], unsigned int dim, _Complex float* out, const _Complex float* in); extern void fixphase2(unsigned int D, const long dims[__VLA(D)], unsigned int dim, const _Complex float rot[__VLA(dims[dim])], _Complex float* out, const _Complex float* in); #include "misc/cppwrap.h" bart-0.5.00/src/misc/version.c000066400000000000000000000002071353046746100161070ustar00rootroot00000000000000 #include "version.h" #define STRINGIFY(x) # x #define VERSION(x) STRINGIFY(x) const char* bart_version = #include "version.inc" ; bart-0.5.00/src/misc/version.h000066400000000000000000000000441353046746100161130ustar00rootroot00000000000000 extern const char* bart_version; bart-0.5.00/src/misc/ya_getopt.c000066400000000000000000000240411353046746100164170ustar00rootroot00000000000000/* -*- indent-tabs-mode: nil -*- * * ya_getopt - Yet another getopt * https://github.com/kubo/ya_getopt * * Copyright 2015 Kubo Takehiro * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of the authors. * */ #include #include #include #include #include "ya_getopt.h" char *ya_optarg = NULL; int ya_optind = 1; int ya_opterr = 1; int ya_optopt = '?'; static char *ya_optnext = NULL; static int posixly_correct = -1; static int handle_nonopt_argv = 0; static void ya_getopt_error(const char *optstring, const char *format, ...); static void check_gnu_extension(const char *optstring); static int ya_getopt_internal(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex, int long_only); static int ya_getopt_shortopts(int argc, char * const argv[], const char *optstring, int long_only); static int ya_getopt_longopts(int argc, char * const argv[], char *arg, const char *optstring, const struct option *longopts, int *longindex, int *long_only_flag); void ya_getopt_reset() { ya_optarg = NULL; ya_optind = 1; ya_opterr = 1; ya_optopt = '?'; ya_optnext = NULL; posixly_correct = -1; handle_nonopt_argv = 0; } static void ya_getopt_error(const char *optstring, const char *format, ...) { if (ya_opterr && optstring[0] != ':') { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } } static void check_gnu_extension(const char *optstring) { if (optstring[0] == '+' || getenv("POSIXLY_CORRECT") != NULL) { posixly_correct = 1; } else { posixly_correct = 0; } if (optstring[0] == '-') { handle_nonopt_argv = 1; } else { handle_nonopt_argv = 0; } } int ya_getopt(int argc, char * const argv[], const char *optstring) { return ya_getopt_internal(argc, argv, optstring, NULL, NULL, 0); } int ya_getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex) { return ya_getopt_internal(argc, argv, optstring, longopts, longindex, 0); } int ya_getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex) { return ya_getopt_internal(argc, argv, optstring, longopts, longindex, 1); } static int ya_getopt_internal(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex, int long_only) { int start = 0; int end = 0; if (ya_optopt == '?') { ya_optopt = 0; } if (posixly_correct == -1) { check_gnu_extension(optstring); } if (ya_optind == 0) { check_gnu_extension(optstring); ya_optind = 1; ya_optnext = NULL; } switch (optstring[0]) { case '+': case '-': optstring++; } if (ya_optnext == NULL && start != 0) { int last_pos = ya_optind - 1; ya_optind -= end - start; if (ya_optind <= 0) { ya_optind = 1; } while (start < end--) { int i; char *arg = argv[end]; for (i = end; i < last_pos; i++) { ((char **)argv)[i] = argv[i + 1]; } ((char const **)argv)[i] = arg; last_pos--; } start = 0; } if (ya_optind >= argc) { ya_optarg = NULL; return -1; } if (ya_optnext == NULL) { const char *arg = argv[ya_optind]; if (*arg != '-') { if (handle_nonopt_argv) { ya_optarg = argv[optind++]; start = 0; return 1; } else if (posixly_correct) { ya_optarg = NULL; return -1; } else { int i; start = ya_optind; for (i = ya_optind + 1; i < argc; i++) { if (argv[i][0] == '-') { end = i; break; } } if (i == argc) { ya_optarg = NULL; return -1; } ya_optind = i; arg = argv[ya_optind]; } } if (strcmp(arg, "--") == 0) { ya_optind++; return -1; } if (longopts != NULL && arg[1] == '-') { return ya_getopt_longopts(argc, argv, argv[ya_optind] + 2, optstring, longopts, longindex, NULL); } } if (ya_optnext == NULL) { ya_optnext = argv[ya_optind] + 1; } if (long_only) { int long_only_flag = 0; int rv = ya_getopt_longopts(argc, argv, ya_optnext, optstring, longopts, longindex, &long_only_flag); if (!long_only_flag) { ya_optnext = NULL; return rv; } } return ya_getopt_shortopts(argc, argv, optstring, long_only); } static int ya_getopt_shortopts(int argc, char * const argv[], const char *optstring, int long_only) { int opt = *ya_optnext; const char *os = strchr(optstring, opt); if (os == NULL) { ya_optarg = NULL; if (long_only) { ya_getopt_error(optstring, "%s: unrecognized option '-%s'\n", argv[0], ya_optnext); ya_optind++; ya_optnext = NULL; } else { ya_optopt = opt; ya_getopt_error(optstring, "%s: invalid option -- '%c'\n", argv[0], opt); if (*(++ya_optnext) == 0) { ya_optind++; ya_optnext = NULL; } } return '?'; } if (os[1] == ':') { if (ya_optnext[1] == 0) { ya_optind++; if (os[2] == ':') { /* optional argument */ ya_optarg = NULL; } else { if (ya_optind == argc) { ya_optarg = NULL; ya_optopt = opt; ya_getopt_error(optstring, "%s: option requires an argument -- '%c'\n", argv[0], opt); if (optstring[0] == ':') { return ':'; } else { return '?'; } } ya_optarg = argv[ya_optind]; ya_optind++; } } else { ya_optarg = ya_optnext + 1; ya_optind++; } ya_optnext = NULL; } else { ya_optarg = NULL; if (ya_optnext[1] == 0) { ya_optnext = NULL; ya_optind++; } else { ya_optnext++; } } return opt; } static int ya_getopt_longopts(int argc, char * const argv[], char *arg, const char *optstring, const struct option *longopts, int *longindex, int *long_only_flag) { char *val = NULL; const struct option *opt; size_t namelen; int idx; for (idx = 0; longopts[idx].name != NULL; idx++) { opt = &longopts[idx]; namelen = strlen(opt->name); if (strncmp(arg, opt->name, namelen) == 0) { switch (arg[namelen]) { case '\0': switch (opt->has_arg) { case ya_required_argument: ya_optind++; if (ya_optind == argc) { ya_optarg = NULL; ya_optopt = opt->val; ya_getopt_error(optstring, "%s: option '--%s' requires an argument\n", argv[0], opt->name); if (optstring[0] == ':') { return ':'; } else { return '?'; } } val = argv[ya_optind]; break; } goto found; case '=': if (opt->has_arg == ya_no_argument) { const char *hyphens = (argv[ya_optind][1] == '-') ? "--" : "-"; ya_optind++; ya_optarg = NULL; ya_optopt = opt->val; ya_getopt_error(optstring, "%s: option '%s%s' doesn't allow an argument\n", argv[0], hyphens, opt->name); return '?'; } val = arg + namelen + 1; goto found; } } } if (long_only_flag) { *long_only_flag = 1; } else { ya_getopt_error(optstring, "%s: unrecognized option '%s'\n", argv[0], argv[ya_optind]); ya_optind++; } return '?'; found: ya_optarg = val; ya_optind++; if (opt->flag) { *opt->flag = opt->val; } if (longindex) { *longindex = idx; } return opt->flag ? 0 : opt->val; } bart-0.5.00/src/misc/ya_getopt.h000066400000000000000000000054541353046746100164330ustar00rootroot00000000000000/* -*- indent-tabs-mode: nil -*- * * ya_getopt - Yet another getopt * https://github.com/kubo/ya_getopt * * Copyright 2015 Kubo Takehiro * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of the authors. * */ #ifndef YA_GETOPT_H #define YA_GETOPT_H 1 #if defined(__cplusplus) extern "C" { #endif #define ya_no_argument 0 #define ya_required_argument 1 #define ya_optional_argument 2 struct option { const char *name; int has_arg; int *flag; int val; }; int ya_getopt(int argc, char * const argv[], const char *optstring); int ya_getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); int ya_getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); void ya_getopt_reset(void); extern char *ya_optarg; extern int ya_optind, ya_opterr, ya_optopt; #ifndef YA_GETOPT_NO_COMPAT_MACRO #define getopt ya_getopt #define getopt_long ya_getopt_long #define getopt_long_only ya_getopt_long_only #define getopt_reset ya_getopt_reset #define optarg ya_optarg #define optind ya_optind #define opterr ya_opterr #define optopt ya_optopt #define no_argument ya_no_argument #define required_argument ya_required_argument #define optional_argument ya_optional_argument #endif #if defined(__cplusplus) } #endif #endif bart-0.5.00/src/moba.c000066400000000000000000000140641353046746100144130ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2019. Uecker Lab, University Medical Center Goettingen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: Xiaoqing Wang, Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/utils.h" #include "misc/opts.h" #include "misc/debug.h" #include "moba/recon_T1.h" static const char usage_str[] = " []"; static const char help_str[] = "Model-based nonlinear inverse reconstruction\n"; int main_moba(int argc, char* argv[]) { double start_time = timestamp(); float restrict_fov = -1.; const char* psf = NULL; struct moba_conf conf = moba_defaults; bool out_sens = false; bool usegpu = false; bool unused = false; enum mdb_t { MDB_T1 } mode = { MDB_T1 }; const struct opt_s opts[] = { OPT_SELECT('L', enum mdb_t, &mode, MDB_T1, "T1 mapping using model-based look-locker"), OPT_UINT('i', &conf.iter, "iter", "Number of Newton steps"), OPT_FLOAT('R', &conf.redu, "", "(reduction factor)"), OPT_FLOAT('j', &conf.alpha_min, "", "Minimum regu. parameter"), OPT_UINT('C', &conf.inner_iter, "iter", "inner iterations"), OPT_FLOAT('s', &conf.step, "step", "step size"), OPT_FLOAT('B', &conf.lower_bound, "bound", "lower bound for relaxivity"), OPT_INT('d', &debug_level, "level", "Debug level"), OPT_SET('N', &unused, "(normalize)"), // no-op OPT_FLOAT('f', &restrict_fov, "FOV", ""), OPT_STRING('p', &psf, "PSF", ""), OPT_SET('g', &usegpu, "use gpu"), }; cmdline(&argc, argv, 2, 4, usage_str, help_str, ARRAY_SIZE(opts), opts); if (5 == argc) out_sens = true; num_init(); long ksp_dims[DIMS]; complex float* kspace_data = load_cfl(argv[1], DIMS, ksp_dims); long TI_dims[DIMS]; complex float* TI = load_cfl(argv[2], DIMS, TI_dims); assert(TI_dims[TE_DIM] == ksp_dims[TE_DIM]); assert(1 == ksp_dims[MAPS_DIM]); long dims[DIMS]; md_copy_dims(DIMS, dims, ksp_dims); long img_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS|MAPS_FLAG|COEFF_FLAG|SLICE_FLAG|TIME2_FLAG, img_dims, dims); img_dims[COEFF_DIM] = 3; long img_strs[DIMS]; md_calc_strides(DIMS, img_strs, img_dims, CFL_SIZE); long single_map_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS|MAPS_FLAG|SLICE_FLAG|TIME2_FLAG, single_map_dims, dims); long single_map_strs[DIMS]; md_calc_strides(DIMS, single_map_strs, single_map_dims, CFL_SIZE); long coil_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS|COIL_FLAG|MAPS_FLAG|SLICE_FLAG|TIME2_FLAG, coil_dims, dims); long coil_strs[DIMS]; md_calc_strides(DIMS, coil_strs, coil_dims, CFL_SIZE); complex float* img = create_cfl(argv[3], DIMS, img_dims); complex float* single_map = create_cfl("", DIMS, single_map_dims); long msk_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS, msk_dims, dims); long msk_strs[DIMS]; md_calc_strides(DIMS, msk_strs, msk_dims, CFL_SIZE); complex float* mask = NULL; complex float* norm = md_alloc(DIMS, img_dims, CFL_SIZE); complex float* sens = (out_sens ? create_cfl : anon_cfl)(out_sens ? argv[4] : "", DIMS, coil_dims); md_zfill(DIMS, img_dims, img, 1.0); md_clear(DIMS, coil_dims, sens, CFL_SIZE); complex float* pattern = NULL; long pat_dims[DIMS]; if (NULL != psf) { complex float* tmp_psf =load_cfl(psf, DIMS, pat_dims); pattern = anon_cfl("", DIMS, pat_dims); md_copy(DIMS, pat_dims, pattern, tmp_psf, CFL_SIZE); unmap_cfl(DIMS, pat_dims, tmp_psf); // FIXME: check compatibility if (-1 == restrict_fov) restrict_fov = 0.5; conf.noncartesian = true; } else { md_copy_dims(DIMS, pat_dims, img_dims); pattern = anon_cfl("", DIMS, pat_dims); estimate_pattern(DIMS, ksp_dims, COIL_FLAG, pattern, kspace_data); } double scaling = 5000. / md_znorm(DIMS, ksp_dims, kspace_data); double scaling_psf = 1000. / md_znorm(DIMS, pat_dims, pattern); debug_printf(DP_INFO, "Scaling: %f\n", scaling); md_zsmul(DIMS, ksp_dims, kspace_data, kspace_data, scaling); debug_printf(DP_INFO, "Scaling_psf: %f\n", scaling_psf); md_zsmul(DIMS, pat_dims, pattern, pattern, scaling_psf); if (-1. == restrict_fov) { mask = md_alloc(DIMS, msk_dims, CFL_SIZE); md_zfill(DIMS, msk_dims, mask, 1.); } else { float restrict_dims[DIMS] = { [0 ... DIMS - 1] = 1. }; restrict_dims[0] = restrict_fov; restrict_dims[1] = restrict_fov; restrict_dims[2] = restrict_fov; mask = compute_mask(DIMS, msk_dims, restrict_dims); //md_zsmul2(DIMS, img_dims, img_strs, img, msk_strs, mask ,1.0); md_zmul2(DIMS, img_dims, img_strs, img, img_strs, img, msk_strs, mask); // Choose a different initial guess for R1* long pos[DIMS]; for (int i = 0; i < (int)DIMS; i++) pos[i] = 0; pos[COEFF_DIM] = 2; md_copy_block(DIMS, pos, single_map_dims, single_map, img_dims, img, CFL_SIZE); md_zsmul2(DIMS, single_map_dims, single_map_strs, single_map, single_map_strs, single_map, 1.5); md_copy_block(DIMS, pos, img_dims, img, single_map_dims, single_map, CFL_SIZE); } // conf.alpha = 0.1; #ifdef USE_CUDA if (usegpu) { complex float* kspace_gpu = md_alloc_gpu(DIMS, ksp_dims, CFL_SIZE); md_copy(DIMS, ksp_dims, kspace_gpu, kspace_data, CFL_SIZE); complex float* TI_gpu = md_alloc_gpu(DIMS, TI_dims, CFL_SIZE); md_copy(DIMS, TI_dims, TI_gpu, TI, CFL_SIZE); switch (mode) { case MDB_T1: T1_recon(&conf, dims, img, sens, pattern, mask, TI_gpu, kspace_gpu, usegpu); break; }; md_free(kspace_gpu); md_free(TI_gpu); } else #endif switch (mode) { case MDB_T1: T1_recon(&conf, dims, img, sens, pattern, mask, TI, kspace_data, usegpu); break; }; md_free(norm); md_free(mask); unmap_cfl(DIMS, coil_dims, sens); unmap_cfl(DIMS, pat_dims, pattern); unmap_cfl(DIMS, img_dims, img); unmap_cfl(DIMS, single_map_dims, single_map); unmap_cfl(DIMS, ksp_dims, kspace_data); unmap_cfl(DIMS, TI_dims, TI); double recosecs = timestamp() - start_time; debug_printf(DP_DEBUG2, "Total Time: %.2f s\n", recosecs); exit(0); } bart-0.5.00/src/moba/000077500000000000000000000000001353046746100142425ustar00rootroot00000000000000bart-0.5.00/src/moba/T1fun.c000066400000000000000000000247551353046746100154200ustar00rootroot00000000000000/* Copyright 2019. Uecker Lab, University Medical Center Goettingen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: Xiaoqing Wang, Martin Uecker */ #include #include "misc/types.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "nlops/nlop.h" #include "T1fun.h" //#define general //#define mphase struct T1_s { INTERFACE(nlop_data_t); int N; const long* map_dims; const long* TI_dims; const long* in_dims; const long* out_dims; const long* map_strs; const long* TI_strs; const long* in_strs; const long* out_strs; // Parameter maps complex float* Mss; complex float* M0; complex float* R1s; complex float* tmp_map; complex float* tmp_ones; complex float* tmp_exp; complex float* tmp_dMss; complex float* tmp_dM0; complex float* tmp_dR1s; complex float* TI; float scaling_M0; float scaling_R1s; }; DEF_TYPEID(T1_s); // Calculate Model: Mss - (Mss + M0) * exp(-t.*R1s) static void T1_fun(const nlop_data_t* _data, complex float* dst, const complex float* src) { struct T1_s* data = CAST_DOWN(T1_s, _data); long pos[data->N]; for (int i = 0; i < data->N; i++) pos[i] = 0; // Mss pos[COEFF_DIM] = 0; md_copy_block(data->N, pos, data->map_dims, data->Mss, data->in_dims, src, CFL_SIZE); // M0 pos[COEFF_DIM] = 1; md_copy_block(data->N, pos, data->map_dims, data->M0, data->in_dims, src, CFL_SIZE); // R1s pos[COEFF_DIM] = 2; md_copy_block(data->N, pos, data->map_dims, data->R1s, data->in_dims, src, CFL_SIZE); // -1*scaling_R1s.*R1s md_zsmul2(data->N, data->map_dims, data->map_strs, data->tmp_map, data->map_strs, data->R1s, -1.0*data->scaling_R1s); // exp(-t.*scaling_R1s*R1s): //#ifdef general // md_zmul2(data->N, data->out_dims, data->out_strs, data->tmp_exp, data->map_strs, data->tmp_map, data->TI_strs, data->TI); #ifdef mphase long map_no_time2_dims[DIMS]; md_select_dims(DIMS, ~TIME2_FLAG, map_no_time2_dims, data->map_dims); long map_no_time2_strs[DIMS]; md_calc_strides(DIMS, map_no_time2_strs, map_no_time2_dims, CFL_SIZE); for (int w = 0; w < (data->TI_dims[11]); w++) for(int k = 0; k < (data->TI_dims[5]); k++) { debug_printf(DP_DEBUG2, "\tTI: %f\n", creal(data->TI[k + data->TI_dims[5]*w])); md_zsmul2(data->N, map_no_time2_dims, map_no_time2_strs, (void*)data->tmp_exp + data->out_strs[5] * k + data->out_strs[11] * w, map_no_time2_strs, (void*)data->tmp_map + data->map_strs[11] * w, data->TI[k + data->TI_dims[5]*w]); } #else for(int k=0; k < (data->TI_dims[5]); k++) md_zsmul2(data->N, data->map_dims, data->out_strs, (void*)data->tmp_exp + data->out_strs[5] * k, data->map_strs, (void*)data->tmp_map, data->TI[k]); #endif long img_dims[data->N]; md_select_dims(data->N, FFT_FLAGS, img_dims, data->map_dims); md_zexp(data->N, data->out_dims, data->tmp_exp, data->tmp_exp); // scaling_M0.*M0 md_zsmul2(data->N, data->map_dims, data->map_strs, data->tmp_map, data->map_strs, data->M0, data->scaling_M0); // Mss + scaling_M0*M0 md_zadd(data->N, data->map_dims, data->tmp_map, data->Mss, data->tmp_map); // (Mss + scaling_M0*M0).*exp(-t.*scaling_R1s*R1s) md_zmul2(data->N, data->out_dims, data->out_strs, dst, data->map_strs, data->tmp_map, data->out_strs, data->tmp_exp); // Mss -(Mss + scaling_M0*M0).*exp(-t.*scaling_R1s*R1s) md_zsub2(data->N, data->out_dims, data->out_strs, dst, data->map_strs, data->Mss, data->out_strs, dst); // Calculating derivatives // M0' = -scaling_M0.*exp(-t.*scaling_R1s.*R1s) md_zsmul(data->N, data->out_dims, data->tmp_dM0, data->tmp_exp, -data->scaling_M0); // Mss' = 1 - exp(-t.*scaling_R1s.*R1s) md_zfill(data->N, data->map_dims, data->tmp_ones, 1.0); md_zsub2(data->N, data->out_dims, data->out_strs, data->tmp_dMss, data->map_strs, data->tmp_ones, data->out_strs, data->tmp_exp); // t*exp(-t.*scaling_R1s*R1s): //#ifdef general //md_zmul2(data->N, data->out_dims, data->out_strs, data->tmp_exp, data->out_strs, data->tmp_exp, data->TI_strs, data->TI); #ifdef mphase for (int s=0; s < data->out_dims[13]; s++) for (int w=0; w < data->TI_dims[11]; w++) for(int k=0; k < data->TI_dims[5]; k++) md_zsmul(data->N, img_dims, (void*)data->tmp_exp + data->out_strs[5] * k + data->out_strs[11] * w + data->out_strs[13] * s, (void*)data->tmp_exp + data->out_strs[5] * k + data->out_strs[11] * w + data->out_strs[13] * s, data->TI[k + data->TI_dims[5] * w]); #else for (int s=0; s < data->out_dims[13]; s++) for(int k=0; k < data->TI_dims[5]; k++) //debug_printf(DP_DEBUG2, "\tTI: %f\n", creal(data->TI[k])); md_zsmul(data->N, img_dims, (void*)data->tmp_exp + data->out_strs[5] * k + data->out_strs[13] * s, (void*)data->tmp_exp + data->out_strs[5] * k + data->out_strs[13] * s, data->TI[k]); #endif // scaling_M0:*exp(-t.*scaling_R1s.*R1s).*t md_zsmul(data->N, data->out_dims, data->tmp_exp, data->tmp_exp, data->scaling_M0); // scaling_M0.*M0 md_zsmul2(data->N, data->map_dims, data->map_strs, data->tmp_map, data->map_strs, data->M0, data->scaling_M0); // Mss + scaling_M0*M0 md_zadd(data->N, data->map_dims, data->tmp_ones, data->Mss, data->tmp_map); // R1s' = (Mss + scaling_M0*M0) * scaling_M0.*exp(-t.*scaling_R1s.*R1s) * t md_zmul2(data->N, data->out_dims, data->out_strs, data->tmp_dR1s, data->map_strs, data->tmp_ones, data->out_strs, data->tmp_exp); } static void T1_der(const nlop_data_t* _data, complex float* dst, const complex float* src) { struct T1_s* data = CAST_DOWN(T1_s, _data); long pos[data->N]; for (int i = 0; i < data->N; i++) pos[i] = 0; // tmp = dM0 pos[COEFF_DIM] = 1; md_copy_block(data->N, pos, data->map_dims, data->tmp_map, data->in_dims, src, CFL_SIZE); //const complex float* tmp_M0 = (const void*)src + md_calc_offset(data->N, data->in_strs, pos); // dst = M0' * dM0 md_zmul2(data->N, data->out_dims, data->out_strs, dst, data->map_strs, data->tmp_map, data->out_strs, data->tmp_dM0); // tmp = dMss pos[COEFF_DIM] = 0; md_copy_block(data->N, pos, data->map_dims, data->tmp_map, data->in_dims, src, CFL_SIZE); //const complex float* tmp_Mss = (const void*)src + md_calc_offset(data->N, data->in_strs, pos); // dst = dst + dMss * Mss' md_zfmac2(data->N, data->out_dims, data->out_strs, dst, data->map_strs, data->tmp_map, data->out_strs, data->tmp_dMss); // tmp = dR1s pos[COEFF_DIM] = 2; md_copy_block(data->N, pos, data->map_dims, data->tmp_map, data->in_dims, src, CFL_SIZE); //const complex float* tmp_R1s = (const void*)src + md_calc_offset(data->N, data->in_strs, pos); // dst = dst + dR1s * R1s' md_zfmac2(data->N, data->out_dims, data->out_strs, dst, data->map_strs, data->tmp_map, data->out_strs, data->tmp_dR1s); } static void T1_adj(const nlop_data_t* _data, complex float* dst, const complex float* src) { struct T1_s* data = CAST_DOWN(T1_s, _data); long pos[data->N]; for (int i = 0; i < data->N; i++) pos[i] = 0; // sum (conj(M0') * src, t) md_clear(data->N, data->map_dims, data->tmp_map, CFL_SIZE); md_zfmacc2(data->N, data->out_dims, data->map_strs, data->tmp_map, data->out_strs, src, data->out_strs, data->tmp_dM0); // dst[1] = sum (conj(M0') * src, t) pos[COEFF_DIM] = 1; md_copy_block(data->N, pos, data->in_dims, dst, data->map_dims, data->tmp_map, CFL_SIZE); // sum (conj(Mss') * src, t) md_clear(data->N, data->map_dims, data->tmp_map, CFL_SIZE); md_zfmacc2(data->N, data->out_dims, data->map_strs, data->tmp_map, data->out_strs, src, data->out_strs, data->tmp_dMss); // dst[0] = sum (conj(Mss') * src, t) pos[COEFF_DIM] = 0; md_copy_block(data->N, pos, data->in_dims, dst, data->map_dims, data->tmp_map, CFL_SIZE); // sum (conj(R1s') * src, t) md_clear(data->N, data->map_dims, data->tmp_map, CFL_SIZE); md_zfmacc2(data->N, data->out_dims, data->map_strs, data->tmp_map, data->out_strs, src, data->out_strs, data->tmp_dR1s); //md_zreal(data->N, data->map_dims, data->tmp_map, data->tmp_map); // dst[2] = sum (conj(R1s') * src, t) pos[COEFF_DIM] = 2; md_copy_block(data->N, pos, data->in_dims, dst, data->map_dims, data->tmp_map, CFL_SIZE); } static void T1_del(const nlop_data_t* _data) { struct T1_s* data = CAST_DOWN(T1_s, _data); md_free(data->Mss); md_free(data->M0); md_free(data->R1s); md_free(data->TI); md_free(data->tmp_map); md_free(data->tmp_ones); md_free(data->tmp_exp); md_free(data->tmp_dM0); md_free(data->tmp_dMss); md_free(data->tmp_dR1s); xfree(data->map_dims); xfree(data->TI_dims); xfree(data->in_dims); xfree(data->out_dims); xfree(data->map_strs); xfree(data->TI_strs); xfree(data->in_strs); xfree(data->out_strs); xfree(data); } struct nlop_s* nlop_T1_create(int N, const long map_dims[N], const long out_dims[N], const long in_dims[N], const long TI_dims[N], const complex float* TI, bool use_gpu) { #ifdef USE_CUDA md_alloc_fun_t my_alloc = use_gpu ? md_alloc_gpu : md_alloc; #else assert(!use_gpu); md_alloc_fun_t my_alloc = md_alloc; #endif PTR_ALLOC(struct T1_s, data); SET_TYPEID(T1_s, data); PTR_ALLOC(long[N], ndims); md_copy_dims(N, *ndims, map_dims); data->map_dims = *PTR_PASS(ndims); PTR_ALLOC(long[N], nodims); md_copy_dims(N, *nodims, out_dims); data->out_dims = *PTR_PASS(nodims); PTR_ALLOC(long[N], nidims); md_copy_dims(N, *nidims, in_dims); data->in_dims = *PTR_PASS(nidims); PTR_ALLOC(long[N], ntidims); md_copy_dims(N, *ntidims, TI_dims); data->TI_dims = *PTR_PASS(ntidims); PTR_ALLOC(long[N], nmstr); md_calc_strides(N, *nmstr, map_dims, CFL_SIZE); data->map_strs = *PTR_PASS(nmstr); PTR_ALLOC(long[N], nostr); md_calc_strides(N, *nostr, out_dims, CFL_SIZE); data->out_strs = *PTR_PASS(nostr); PTR_ALLOC(long[N], nistr); md_calc_strides(N, *nistr, in_dims, CFL_SIZE); data->in_strs = *PTR_PASS(nistr); PTR_ALLOC(long[N], ntistr); md_calc_strides(N, *ntistr, TI_dims, CFL_SIZE); data->TI_strs = *PTR_PASS(ntistr); data->N = N; data->Mss = my_alloc(N, map_dims, CFL_SIZE); data->M0 = my_alloc(N, map_dims, CFL_SIZE); data->R1s = my_alloc(N, map_dims, CFL_SIZE); data->tmp_map = my_alloc(N, map_dims, CFL_SIZE); data->tmp_ones = my_alloc(N, map_dims, CFL_SIZE); data->tmp_exp = my_alloc(N, out_dims, CFL_SIZE); data->tmp_dM0 = my_alloc(N, out_dims, CFL_SIZE); data->tmp_dMss = my_alloc(N, out_dims, CFL_SIZE); data->tmp_dR1s = my_alloc(N, out_dims, CFL_SIZE); #ifdef general data->TI = my_alloc(N, TI_dims, CFL_SIZE); #else data->TI = md_alloc(N, TI_dims, CFL_SIZE); #endif md_copy(N, TI_dims, data->TI, TI, CFL_SIZE); data->scaling_M0 = 2.0; data->scaling_R1s = 1.0; return nlop_create(N, out_dims, N, in_dims, CAST_UP(PTR_PASS(data)), T1_fun, T1_der, T1_adj, NULL, NULL, T1_del); } bart-0.5.00/src/moba/T1fun.h000066400000000000000000000003551353046746100154130ustar00rootroot00000000000000 struct nlop_s; struct noir_model_conf_s; extern struct nlop_s* nlop_T1_create(int N, const long map_dims[N], const long out_dims[N], const long in_dims[N], const long TI_dims[N], const complex float* TI, bool use_gpu); bart-0.5.00/src/moba/iter_l1.c000066400000000000000000000164431353046746100157550ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2019. Uecker Lab, University Medical Center Goettingen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: Xiaoqing Wang, Martin Uecker */ #include #include #include #include #include "misc/types.h" #include "misc/mri.h" #include "misc/debug.h" #include "misc/misc.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/ops_p.h" #include "num/rand.h" #include "num/ops.h" #include "num/iovec.h" #include "wavelet/wavthresh.h" #include "nlops/nlop.h" #include "iter/prox.h" #include "iter/vec.h" #include "iter/italgos.h" #include "iter/iter3.h" #include "iter/iter2.h" #include "iter_l1.h" struct T1inv_s { INTERFACE(iter_op_data); const struct nlop_s* nlop; const struct mdb_irgnm_l1_conf* conf; long size_x; long size_y; float alpha; const long* dims; bool first_iter; int outer_iter; const struct operator_p_s* prox1; const struct operator_p_s* prox2; }; DEF_TYPEID(T1inv_s); static void normal_fista(iter_op_data* _data, float* dst, const float* src) { auto data = CAST_DOWN(T1inv_s, _data); float* tmp = md_alloc_sameplace(1, MD_DIMS(data->size_y), FL_SIZE, src); linop_forward_unchecked(nlop_get_derivative(data->nlop, 0, 0), (complex float*)tmp, (const complex float*)src); linop_adjoint_unchecked(nlop_get_derivative(data->nlop, 0, 0), (complex float*)dst, (const complex float*)tmp); md_free(tmp); long res = data->dims[0]; long parameters = data->dims[COEFF_DIM]; long coils = data->dims[COIL_DIM]; md_axpy(1, MD_DIMS(data->size_x * coils / (coils + parameters)), dst + res * res * 2 * parameters, data->alpha, src + res * res * 2 * parameters); } static void pos_value(iter_op_data* _data, float* dst, const float* src) { auto data = CAST_DOWN(T1inv_s, _data); long res = data->dims[0]; long parameters = data->dims[COEFF_DIM]; long dims1[DIMS]; md_select_dims(DIMS, FFT_FLAGS, dims1, data->dims); md_zsmax(DIMS, dims1, (_Complex float*)dst + (parameters - 1) * res * res, (const _Complex float*)src + (parameters - 1) * res * res, data->conf->lower_bound); } static void combined_prox(iter_op_data* _data, float rho, float* dst, const float* src) { struct T1inv_s* data = CAST_DOWN(T1inv_s, _data); if (data->first_iter) { data->first_iter = false; } else { pos_value(_data, dst, src); } operator_p_apply_unchecked(data->prox2, rho, (_Complex float*)dst, (const _Complex float*)dst); pos_value(_data, dst, dst); } static void inverse_fista(iter_op_data* _data, float alpha, float* dst, const float* src) { auto data = CAST_DOWN(T1inv_s, _data); data->alpha = alpha; // update alpha for normal operator void* x = md_alloc_sameplace(1, MD_DIMS(data->size_x), FL_SIZE, src); md_gaussian_rand(1, MD_DIMS(data->size_x / 2), x); double maxeigen = power(20, data->size_x, select_vecops(src), (struct iter_op_s){ normal_fista, CAST_UP(data) }, x); md_free(x); double step = data->conf->step / maxeigen; debug_printf(DP_DEBUG3, "##reg. alpha = %f\n", alpha); wavthresh_rand_state_set(data->prox1, 1); int maxiter = MIN(data->conf->c2->cgiter, 10 * powf(2, data->outer_iter)); float* tmp = md_alloc_sameplace(1, MD_DIMS(data->size_y), FL_SIZE, src); linop_adjoint_unchecked(nlop_get_derivative(data->nlop, 0, 0), (complex float*)tmp, (const complex float*)src); float eps = md_norm(1, MD_DIMS(data->size_x), tmp); data->first_iter = true; NESTED(void, continuation, (struct ist_data* itrdata)) { itrdata->scale = data->alpha; }; fista(maxiter, data->conf->c2->cgtol * alpha * eps, step, data->size_x, select_vecops(src), continuation, (struct iter_op_s){ normal_fista, CAST_UP(data) }, (struct iter_op_p_s){ combined_prox, CAST_UP(data) }, dst, tmp, NULL); pos_value(CAST_UP(data), dst, dst); md_free(tmp); data->outer_iter++; } static const struct operator_p_s* create_prox(const long img_dims[DIMS]) { bool randshift = true; long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; unsigned int wflags = 0; for (unsigned int i = 0; i < DIMS; i++) { if ((1 < img_dims[i]) && MD_IS_SET(FFT_FLAGS, i)) { wflags = MD_SET(wflags, i); minsize[i] = MIN(img_dims[i], DIMS); } } return prox_wavelet_thresh_create(DIMS, img_dims, wflags, COEFF_FLAG, minsize, 1., randshift); } struct T1inv2_s { INTERFACE(operator_data_t); struct T1inv_s data; }; DEF_TYPEID(T1inv2_s); static void T1inv_apply(const operator_data_t* _data, float alpha, complex float* dst, const complex float* src) { const auto data = &CAST_DOWN(T1inv2_s, _data)->data; inverse_fista(CAST_UP(data), alpha, (float*)dst, (const float*)src); } static void T1inv_del(const operator_data_t* _data) { auto data = CAST_DOWN(T1inv2_s, _data); operator_p_free(data->data.prox1); operator_p_free(data->data.prox2); nlop_free(data->data.nlop); xfree(data->data.dims); xfree(data); } static const struct operator_p_s* T1inv_p_create(const struct mdb_irgnm_l1_conf* conf, const long dims[DIMS], struct nlop_s* nlop) { PTR_ALLOC(struct T1inv2_s, data); SET_TYPEID(T1inv2_s, data); SET_TYPEID(T1inv_s, &data->data); auto cd = nlop_codomain(nlop); auto dm = nlop_domain(nlop); int M = 2 * md_calc_size(cd->N, cd->dims); int N = 2 * md_calc_size(dm->N, dm->dims); long* ndims = *TYPE_ALLOC(long[DIMS]); md_copy_dims(DIMS, ndims, dims); long img_dims[DIMS]; md_select_dims(DIMS, ~COIL_FLAG, img_dims, dims); debug_print_dims(DP_INFO, DIMS, img_dims); auto prox1 = create_prox(img_dims); auto prox2 = op_p_auto_normalize(prox1, ~COEFF_FLAG); struct T1inv_s idata = { { &TYPEID(T1inv_s) }, nlop_clone(nlop), conf, N, M, 1.0, ndims, true, 0, prox1, prox2 }; data->data = idata; return operator_p_create(dm->N, dm->dims, cd->N, cd->dims, CAST_UP(PTR_PASS(data)), T1inv_apply, T1inv_del); } struct iterT1_nlop_s { INTERFACE(iter_op_data); struct nlop_s nlop; }; DEF_TYPEID(iterT1_nlop_s); static void nlop_for_iter(iter_op_data* _o, float* _dst, const float* _src) { const auto nlop = CAST_DOWN(iterT1_nlop_s, _o); operator_apply_unchecked(nlop->nlop.op, (complex float*)_dst, (const complex float*)_src); } static void nlop_der_iter(iter_op_data* _o, float* _dst, const float* _src) { const auto nlop = CAST_DOWN(iterT1_nlop_s, _o); assert(2 == operator_nr_args(nlop->nlop.op)); linop_forward_unchecked(nlop->nlop.derivative[0], (complex float*)_dst, (const complex float*)_src); } void mdb_irgnm_l1(const struct mdb_irgnm_l1_conf* conf, const long dims[], struct nlop_s* nlop, long N, float* dst, long M, const float* src) { auto cd = nlop_codomain(nlop); auto dm = nlop_domain(nlop); assert(M * sizeof(float) == md_calc_size(cd->N, cd->dims) * cd->size); assert(N * sizeof(float) == md_calc_size(dm->N, dm->dims) * dm->size); struct iterT1_nlop_s nl_data = { { &TYPEID(iterT1_nlop_s) }, *nlop }; const struct operator_p_s* inv_op = T1inv_p_create(conf, dims, nlop); irgnm2(conf->c2->iter, conf->c2->alpha, 0., conf->c2->alpha_min, conf->c2->redu, N, M, select_vecops(src), (struct iter_op_s){ nlop_for_iter, CAST_UP(&nl_data) }, (struct iter_op_s){ nlop_der_iter, CAST_UP(&nl_data) }, OPERATOR_P2ITOP(inv_op), dst, NULL, src, (struct iter_op_s){ NULL, NULL }, NULL); operator_p_free(inv_op); } bart-0.5.00/src/moba/iter_l1.h000066400000000000000000000005151353046746100157530ustar00rootroot00000000000000 struct iter3_irgnm_conf; struct nlop_s; #ifndef DIMS #define DIMS 16 #endif struct mdb_irgnm_l1_conf { struct iter3_irgnm_conf* c2; float step; float lower_bound; }; void mdb_irgnm_l1(const struct mdb_irgnm_l1_conf* conf, const long dims[DIMS], struct nlop_s* nlop, long N, float* dst, long M, const float* src); bart-0.5.00/src/moba/model_T1.c000066400000000000000000000040651353046746100160570ustar00rootroot00000000000000/* Copyright 2019. Uecker Lab, University Medical Center Goettingen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: Xiaoqing Wang, Martin Uecker */ #include #include #include #include #include #include "misc/misc.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/debug.h" #include "nlops/nlop.h" #include "nlops/chain.h" #include "nlops/cast.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "noir/model.h" #include "moba/T1fun.h" #include "model_T1.h" struct T1_s T1_create(const long dims[DIMS], const complex float* mask, const complex float* TI, const complex float* psf, const struct noir_model_conf_s* conf, _Bool use_gpu) { struct noir_s nlinv = noir_create3(dims, mask, psf, conf); struct T1_s ret; long map_dims[DIMS]; long out_dims[DIMS]; long in_dims[DIMS]; long TI_dims[DIMS]; md_select_dims(DIMS, conf->fft_flags|TIME2_FLAG, map_dims, dims); md_select_dims(DIMS, conf->fft_flags|TE_FLAG|TIME2_FLAG, out_dims, dims); md_select_dims(DIMS, conf->fft_flags|COEFF_FLAG|TIME2_FLAG, in_dims, dims); md_select_dims(DIMS, TE_FLAG|TIME2_FLAG, TI_dims, dims); in_dims[COEFF_DIM] = 3; #if 1 // chain T1 model struct nlop_s* T1 = nlop_T1_create(DIMS, map_dims, out_dims, in_dims, TI_dims, TI, use_gpu); debug_print_dims(DP_INFO, DIMS, nlop_generic_domain(T1, 0)->dims); debug_print_dims(DP_INFO, DIMS, nlop_generic_codomain(T1, 0)->dims); debug_print_dims(DP_INFO, DIMS, nlop_generic_domain(nlinv.nlop, 0)->dims); debug_print_dims(DP_INFO, DIMS, nlop_generic_domain(nlinv.nlop, 1)->dims); debug_print_dims(DP_INFO, DIMS, nlop_generic_codomain(nlinv.nlop, 0)->dims); const struct nlop_s* b = nlinv.nlop; const struct nlop_s* c = nlop_chain2(T1, 0, b, 0); nlop_free(b); nlinv.nlop = nlop_permute_inputs(c, 2, (const int[2]){ 1, 0 }); nlop_free(c); #endif ret.nlop = nlop_flatten(nlinv.nlop); ret.linop = nlinv.linop; nlop_free(nlinv.nlop); return ret; } bart-0.5.00/src/moba/model_T1.h000066400000000000000000000005261353046746100160620ustar00rootroot00000000000000 #include "misc/mri.h" struct linop_s; struct nlop_s; struct noir_model_conf_s; struct T1_s { struct nlop_s* nlop; const struct linop_s* linop; }; extern struct T1_s T1_create(const long dims[DIMS], const complex float* mask, const complex float* TI, const complex float* psf, const struct noir_model_conf_s* conf, _Bool use_gpu); bart-0.5.00/src/moba/recon_T1.c000066400000000000000000000065151353046746100160670ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2019. Uecker Lab, University Medical Center Goettingen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: Xiaoqing Wang, Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "iter/iter3.h" #include "nlops/nlop.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/mri.h" #include "misc/debug.h" #include "noir/model.h" #include "noir/recon.h" #include "moba/model_T1.h" #include "moba/iter_l1.h" #include "recon_T1.h" struct moba_conf moba_defaults = { .iter = 8, .alpha = 1., .alpha_min = 0., .redu = 2., .step = 0.9, .lower_bound = 0., .tolerance = 0.01, .inner_iter = 250, .noncartesian = false, }; void T1_recon(const struct moba_conf* conf, const long dims[DIMS], complex float* img, complex float* sens, const complex float* pattern, const complex float* mask, const complex float* TI, const complex float* kspace_data, _Bool usegpu) { long imgs_dims[DIMS]; long coil_dims[DIMS]; long data_dims[DIMS]; long img1_dims[DIMS]; unsigned int fft_flags = FFT_FLAGS|SLICE_FLAG; md_select_dims(DIMS, fft_flags|MAPS_FLAG|CSHIFT_FLAG|COEFF_FLAG|TIME2_FLAG, imgs_dims, dims); md_select_dims(DIMS, fft_flags|COIL_FLAG|MAPS_FLAG|TIME2_FLAG, coil_dims, dims); md_select_dims(DIMS, fft_flags|COIL_FLAG|TE_FLAG|TIME2_FLAG, data_dims, dims); md_select_dims(DIMS, fft_flags|TIME2_FLAG, img1_dims, dims); imgs_dims[COEFF_DIM] = 3; long skip = md_calc_size(DIMS, imgs_dims); long size = skip + md_calc_size(DIMS, coil_dims); long data_size = md_calc_size(DIMS, data_dims); long d1[1] = { size }; // variable which is optimized by the IRGNM complex float* x = md_alloc_sameplace(1, d1, CFL_SIZE, kspace_data); md_copy(DIMS, imgs_dims, x, img, CFL_SIZE); md_copy(DIMS, coil_dims, x + skip, sens, CFL_SIZE); struct noir_model_conf_s mconf = noir_model_conf_defaults; mconf.rvc = false; mconf.noncart = conf->noncartesian; mconf.fft_flags = fft_flags; mconf.a = 880.; mconf.b = 32.; struct T1_s nl = T1_create(dims, mask, TI, pattern, &mconf, usegpu); struct iter3_irgnm_conf irgnm_conf = iter3_irgnm_defaults; irgnm_conf.iter = conf->iter; irgnm_conf.alpha = conf->alpha; irgnm_conf.redu = conf->redu; irgnm_conf.alpha_min = conf->alpha_min; irgnm_conf.cgtol = conf->tolerance; irgnm_conf.cgiter = conf->inner_iter; irgnm_conf.nlinv_legacy = true; struct mdb_irgnm_l1_conf conf2 = { .c2 = &irgnm_conf, .step = conf->step, .lower_bound = conf->lower_bound }; long irgnm_conf_dims[DIMS]; md_select_dims(DIMS, fft_flags|MAPS_FLAG|CSHIFT_FLAG|COEFF_FLAG|TIME2_FLAG, irgnm_conf_dims, imgs_dims); irgnm_conf_dims[COIL_DIM] = coil_dims[COIL_DIM]; debug_printf(DP_INFO, "imgs_dims:\n\t"); debug_print_dims(DP_INFO, DIMS, irgnm_conf_dims); mdb_irgnm_l1(&conf2, irgnm_conf_dims, nl.nlop, size * 2, (float*)x, data_size * 2, (const float*)kspace_data); md_copy(DIMS, imgs_dims, img, x, CFL_SIZE); if (NULL != sens) { noir_forw_coils(nl.linop, x + skip, x + skip); md_copy(DIMS, coil_dims, sens, x + skip, CFL_SIZE); fftmod(DIMS, coil_dims, fft_flags, sens, sens); } nlop_free(nl.nlop); md_free(x); } bart-0.5.00/src/moba/recon_T1.h000066400000000000000000000010511353046746100160620ustar00rootroot00000000000000 #ifndef RECON_T1_H #define RECON_T1_H #include "misc/mri.h" struct moba_conf { unsigned int iter; float alpha; float alpha_min; float redu; float step; float lower_bound; float tolerance; unsigned int inner_iter; bool noncartesian; }; extern struct moba_conf moba_defaults; extern void T1_recon(const struct moba_conf* conf, const long dims[DIMS], _Complex float* img, _Complex float* sens, const _Complex float* pattern, const _Complex float* mask, const _Complex float* TI, const _Complex float* kspace_data, _Bool usegpu); #endif bart-0.5.00/src/nlinv.c000066400000000000000000000172121353046746100146210ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/utils.h" #include "misc/opts.h" #include "misc/debug.h" #include "noir/recon.h" static const char usage_str[] = " []"; static const char help_str[] = "Jointly estimate image and sensitivities with nonlinear\n" "inversion using {iter} iteration steps. Optionally outputs\n" "the sensitivities."; int main_nlinv(int argc, char* argv[]) { double start_time = timestamp(); bool normalize = true; bool combine = true; unsigned int nmaps = 1; float restrict_fov = -1.; const char* psf = NULL; const char* init_file = NULL; struct noir_conf_s conf = noir_defaults; bool out_sens = false; bool scale_im = false; bool usegpu = false; const struct opt_s opts[] = { OPT_UINT('i', &conf.iter, "iter", "Number of Newton steps"), OPT_FLOAT('R', &conf.redu, "", "(reduction factor)"), OPT_FLOAT('M', &conf.alpha_min, "", "(minimum for regularization)"), OPT_INT('d', &debug_level, "level", "Debug level"), OPT_SET('c', &conf.rvc, "Real-value constraint"), OPT_CLEAR('N', &normalize, "Do not normalize image with coil sensitivities"), OPT_UINT('m', &nmaps, "nmaps", "Number of ENLIVE maps to use in reconsctruction"), OPT_CLEAR('U', &combine, "Do not combine ENLIVE maps in output"), OPT_FLOAT('f', &restrict_fov, "FOV", ""), OPT_STRING('p', &psf, "PSF", ""), OPT_STRING('I', &init_file, "file", "File for initialization"), OPT_SET('g', &usegpu, "use gpu"), OPT_SET('S', &scale_im, "Re-scale image after reconstruction"), OPT_FLOAT('a', &conf.a, "", "(a in 1 + a * \\Laplace^-b/2)"), OPT_FLOAT('b', &conf.b, "", "(b in 1 + a * \\Laplace^-b/2)"), OPT_SET('P', &conf.pattern_for_each_coil, "(supplied psf is different for each coil)"), }; cmdline(&argc, argv, 2, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (4 == argc) out_sens = true; num_init(); long ksp_dims[DIMS]; complex float* kspace_data = load_cfl(argv[1], DIMS, ksp_dims); // FIXME: SMS should not be the default if (1 != ksp_dims[SLICE_DIM]) { debug_printf(DP_INFO, "SMS-NLINV reconstruction. Multiband factor: %d\n", ksp_dims[SLICE_DIM]); fftmod(DIMS, ksp_dims, SLICE_FLAG, kspace_data, kspace_data); // fftmod to get correct slice order in output conf.sms = true; } // The only multimap we understand with is the one we do ourselves, where // we allow multiple images and sensitivities during the reconsctruction assert(1 == ksp_dims[MAPS_DIM]); long ksp_strs[DIMS]; md_calc_strides(DIMS, ksp_strs, ksp_dims, CFL_SIZE); long sens_dims[DIMS]; md_copy_dims(DIMS, sens_dims, ksp_dims); sens_dims[MAPS_DIM] = nmaps; long sens_strs[DIMS]; md_calc_strides(DIMS, sens_strs, sens_dims, CFL_SIZE); long img_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS|MAPS_FLAG|SLICE_FLAG, img_dims, sens_dims); long img_strs[DIMS]; md_calc_strides(DIMS, img_strs, img_dims, CFL_SIZE); long img_output_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS|SLICE_FLAG, img_output_dims, sens_dims); if (!combine) img_output_dims[MAPS_DIM] = nmaps; long img_output_strs[DIMS]; md_calc_strides(DIMS, img_output_strs, img_output_dims, CFL_SIZE); complex float* img_output = create_cfl(argv[2], DIMS, img_output_dims); md_clear(DIMS, img_output_dims, img_output, CFL_SIZE); complex float* img = md_alloc(DIMS, img_dims, CFL_SIZE); long msk_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS, msk_dims, img_dims); long msk_strs[DIMS]; md_calc_strides(DIMS, msk_strs, msk_dims, CFL_SIZE); complex float* mask = NULL; complex float* ksens = md_alloc(DIMS, sens_dims, CFL_SIZE); complex float* sens = (out_sens ? create_cfl : anon_cfl)(out_sens ? argv[3] : "", DIMS, sens_dims); // initialization if (NULL != init_file) { long skip = md_calc_size(DIMS, img_dims); long init_dims[DIMS]; complex float* init = load_cfl(init_file, DIMS, init_dims); assert(md_check_bounds(DIMS, 0, img_dims, init_dims)); md_copy(DIMS, img_dims, img, init, CFL_SIZE); fftmod(DIMS, sens_dims, FFT_FLAGS|SLICE_FLAG, ksens, init + skip); unmap_cfl(DIMS, init_dims, init); } else { md_zfill(DIMS, img_dims, img, 1.); md_clear(DIMS, sens_dims, ksens, CFL_SIZE); } complex float* pattern = NULL; long pat_dims[DIMS]; if (NULL != psf) { complex float* tmp_psf =load_cfl(psf, DIMS, pat_dims); pattern = anon_cfl("", DIMS, pat_dims); md_copy(DIMS, pat_dims, pattern, tmp_psf, CFL_SIZE); unmap_cfl(DIMS, pat_dims, tmp_psf); // FIXME: check compatibility if (conf.pattern_for_each_coil) { assert( 1 != pat_dims[COIL_DIM] ); } else { if (-1 == restrict_fov) restrict_fov = 0.5; conf.noncart = true; } } else { md_copy_dims(DIMS, pat_dims, img_dims); pattern = anon_cfl("", DIMS, pat_dims); estimate_pattern(DIMS, ksp_dims, COIL_FLAG, pattern, kspace_data); } #if 0 float scaling = 1. / estimate_scaling(ksp_dims, NULL, kspace_data); #else double scaling = 100. / md_znorm(DIMS, ksp_dims, kspace_data); if (1 != ksp_dims[SLICE_DIM]) // SMS scaling *= sqrt(ksp_dims[SLICE_DIM]); #endif debug_printf(DP_INFO, "Scaling: %f\n", scaling); md_zsmul(DIMS, ksp_dims, kspace_data, kspace_data, scaling); if (-1. == restrict_fov) { mask = md_alloc(DIMS, msk_dims, CFL_SIZE); md_zfill(DIMS, msk_dims, mask, 1.); } else { float restrict_dims[DIMS] = { [0 ... DIMS - 1] = 1. }; restrict_dims[0] = restrict_fov; restrict_dims[1] = restrict_fov; restrict_dims[2] = restrict_fov; mask = compute_mask(DIMS, msk_dims, restrict_dims); } complex float* ref = NULL; #ifdef USE_CUDA if (usegpu) { complex float* kspace_gpu = md_alloc_gpu(DIMS, ksp_dims, CFL_SIZE); md_copy(DIMS, ksp_dims, kspace_gpu, kspace_data, CFL_SIZE); noir_recon(&conf, sens_dims, img, sens, ksens, ref, pattern, mask, kspace_gpu); md_free(kspace_gpu); } else #endif noir_recon(&conf, sens_dims, img, sens, ksens, ref, pattern, mask, kspace_data); // image output if (normalize) { complex float* buf = md_alloc(DIMS, sens_dims, CFL_SIZE); md_clear(DIMS, sens_dims, buf, CFL_SIZE); if (combine) { md_zfmac2(DIMS, sens_dims, ksp_strs, buf, img_strs, img, sens_strs, sens); md_zrss(DIMS, ksp_dims, COIL_FLAG, img_output, buf); } else { md_zfmac2(DIMS, sens_dims, sens_strs, buf, img_strs, img, sens_strs, sens); md_zrss(DIMS, sens_dims, COIL_FLAG, img_output, buf); } md_zmul2(DIMS, img_output_dims, img_output_strs, img_output, img_output_strs, img_output, msk_strs, mask); if (1 == nmaps || !combine) { //restore phase md_zphsr(DIMS, img_output_dims, buf, img); md_zmul(DIMS, img_output_dims, img_output, img_output, buf); } md_free(buf); } else { if (combine) { // just sum up the map images md_zaxpy2(DIMS, img_dims, img_output_strs, img_output, 1., img_strs, img); } else { /*!normalize && !combine */ // Just copy md_copy(DIMS, img_output_dims, img_output, img, CFL_SIZE); } } if (scale_im) md_zsmul(DIMS, img_output_dims, img_output, img_output, 1. / scaling); md_free(mask); md_free(img); unmap_cfl(DIMS, sens_dims, sens); unmap_cfl(DIMS, pat_dims, pattern); unmap_cfl(DIMS, img_output_dims, img_output); unmap_cfl(DIMS, ksp_dims, kspace_data); double recosecs = timestamp() - start_time; debug_printf(DP_DEBUG2, "Total Time: %.2f s\n", recosecs); exit(0); } bart-0.5.00/src/nlops/000077500000000000000000000000001353046746100144575ustar00rootroot00000000000000bart-0.5.00/src/nlops/cast.c000066400000000000000000000041011353046746100155510ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include "misc/types.h" #include "misc/misc.h" #include "num/iovec.h" #include "linops/linop.h" #include "nlops/nlop.h" #include "cast.h" struct nlop_linop_s { INTERFACE(nlop_data_t); const struct linop_s* lop; }; DEF_TYPEID(nlop_linop_s); static void lop_fun(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(nlop_linop_s, _data); linop_forward_unchecked(data->lop, dst, src); } static void lop_adj(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(nlop_linop_s, _data); linop_adjoint_unchecked(data->lop, dst, src); } static void lop_norm(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(nlop_linop_s, _data); linop_normal_unchecked(data->lop, dst, src); } static void lop_inv(const nlop_data_t* _data, float alpha, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(nlop_linop_s, _data); linop_norm_inv_unchecked(data->lop, alpha, dst, src); } static void lop_del(const nlop_data_t* _data) { const auto data = CAST_DOWN(nlop_linop_s, _data); linop_free(data->lop); xfree(data); } struct nlop_s* nlop_from_linop(const struct linop_s* x) { PTR_ALLOC(struct nlop_linop_s, data); SET_TYPEID(nlop_linop_s, data); data->lop = linop_clone(x); const struct iovec_s* dom = linop_domain(x); const struct iovec_s* cod = linop_codomain(x); return nlop_create2(cod->N, cod->dims, cod->strs, dom->N, dom->dims, dom->strs, CAST_UP(PTR_PASS(data)), lop_fun, lop_fun, lop_adj, lop_norm, lop_inv, lop_del); } const struct linop_s* linop_from_nlop(const struct nlop_s* x) { struct nlop_data_s* data = nlop_get_data((struct nlop_s*)x); auto ldata = CAST_MAYBE(nlop_linop_s, data); return (NULL != ldata) ? ldata->lop : NULL; } bart-0.5.00/src/nlops/cast.h000066400000000000000000000002301353046746100155550ustar00rootroot00000000000000 struct linop_s; extern struct nlop_s* nlop_from_linop(const struct linop_s*); extern const struct linop_s* linop_from_nlop(const struct nlop_s* x); bart-0.5.00/src/nlops/chain.c000066400000000000000000000127331353046746100157130ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include #include "num/ops.h" #include "num/iovec.h" #include "misc/misc.h" #include "nlops/nlop.h" #include "nlops/cast.h" #include "linops/linop.h" #include "chain.h" struct nlop_s* nlop_chain(const struct nlop_s* a, const struct nlop_s* b) { assert(1 == nlop_get_nr_in_args(a)); assert(1 == nlop_get_nr_out_args(a)); assert(1 == nlop_get_nr_in_args(b)); assert(1 == nlop_get_nr_out_args(b)); const struct linop_s* la = linop_from_nlop(a); const struct linop_s* lb = linop_from_nlop(b); if ((NULL != la) && (NULL != lb)) return nlop_from_linop(linop_chain(la, lb)); PTR_ALLOC(struct nlop_s, n); const struct linop_s* (*der)[1][1] = TYPE_ALLOC(const struct linop_s*[1][1]); n->derivative = &(*der)[0][0]; if (NULL == la) la = a->derivative[0]; if (NULL == lb) lb = b->derivative[0]; n->op = operator_chain(a->op, b->op); n->derivative[0] = linop_chain(la, lb); return PTR_PASS(n); } struct nlop_s* nlop_chain_FF(const struct nlop_s* a, const struct nlop_s* b) { struct nlop_s* x = nlop_chain(a, b); nlop_free(a); nlop_free(b); return x; } struct nlop_s* nlop_chain2(const struct nlop_s* a, int o, const struct nlop_s* b, int i) { // int ai = nlop_get_nr_in_args(a); int ao = nlop_get_nr_out_args(a); // int bi = nlop_get_nr_in_args(b); // int bo = nlop_get_nr_out_args(b); #if 0 if ((1 == ai) && (1 == ao) && (1 == bi) && (1 == bo)) { assert((0 == o) && (0 == i)); return nlop_chain(a, b); } #endif struct nlop_s* nl = nlop_combine(b, a); struct nlop_s* li = nlop_link(nl, ao + o, i); nlop_free(nl); return li; } /* * CAVE: if we pass the same operator twice, it might not * as they store state with respect to the derivative */ struct nlop_s* nlop_combine(const struct nlop_s* a, const struct nlop_s* b) { assert(a != b); // could also be deeply nested, but we do not detect it int ai = nlop_get_nr_in_args(a); int ao = nlop_get_nr_out_args(a); int bi = nlop_get_nr_in_args(b); int bo = nlop_get_nr_out_args(b); PTR_ALLOC(struct nlop_s, n); int II = ai + bi; int OO = ao + bo; const struct linop_s* (*der)[II][OO] = TYPE_ALLOC(const struct linop_s*[II][OO]); n->derivative = &(*der)[0][0]; for (int i = 0; i < II; i++) { for (int o = 0; o < OO; o++) { if ((i < ai) && (o < ao)) (*der)[i][o] = linop_clone(nlop_get_derivative(a, o, i)); else if ((ai <= i) && (ao <= o)) (*der)[i][o] = linop_clone(nlop_get_derivative(b, o - ao, i - ai)); else if ((i < ai) && (ao <= o)) { auto dom = nlop_generic_domain(a, i); auto cod = nlop_generic_codomain(b, o - ao); //assert(dom->N == cod->N); assert(sizeof(complex float) == dom->size); assert(sizeof(complex float) == cod->size); (*der)[i][o] = linop_null_create2(dom->N, cod->dims, cod->strs, dom->dims, dom->strs); } else if ((ai <= i) && (o < ao)) { auto dom = nlop_generic_domain(b, i - ai); auto cod = nlop_generic_codomain(a, o); assert(dom->N == cod->N); assert(sizeof(complex float) == dom->size); assert(sizeof(complex float) == cod->size); (*der)[i][o] = linop_null_create2(dom->N, cod->dims, cod->strs, dom->dims, dom->strs); } } } n->op = operator_combi_create(2, (const struct operator_s*[]){ a->op, b->op }); assert(II == (int)operator_nr_in_args(n->op)); assert(OO == (int)operator_nr_out_args(n->op)); int perm[II + OO]; // ao ai bo bi -> ao bo ai bi int p = 0; for (int i = 0; i < ao; i++) perm[p++] = i; for (int i = 0; i < bo; i++) perm[p++] = (ao + ai + i); for (int i = 0; i < ai; i++) perm[p++] = (ao + i); for (int i = 0; i < bi; i++) perm[p++] = (ao + ai + bo + i); assert(II + OO == p); n->op = operator_permute(n->op, II + OO, perm); return PTR_PASS(n); } struct nlop_s* nlop_link(const struct nlop_s* x, int oo, int ii) { int II = nlop_get_nr_in_args(x); int OO = nlop_get_nr_out_args(x); assert(ii < II); assert(oo < OO); PTR_ALLOC(struct nlop_s, n); PTR_ALLOC(const struct linop_s*[II - 1][OO - 1], der); assert(operator_ioflags(x->op) == ((1u << OO) - 1)); n->op = operator_link_create(x->op, oo, OO + ii); assert(operator_ioflags(n->op) == ((1u << (OO - 1)) - 1)); // f(x_1, ..., g(x_n+1, ..., x_n+m), ..., xn) for (int i = 0, ip = 0; i < II - 1; i++, ip++) { if (i == ii) ip++; for (int o = 0, op = 0; o < OO - 1; o++, op++) { if (o == oo) op++; const struct linop_s* tmp = linop_chain(nlop_get_derivative(x, oo, ip), nlop_get_derivative(x, op, ii)); (*der)[i][o] = linop_plus( nlop_get_derivative(x, op, ip), tmp); linop_free(tmp); } } n->derivative = &(*PTR_PASS(der))[0][0]; return PTR_PASS(n); } struct nlop_s* nlop_permute_inputs(const struct nlop_s* x, int I2, const int perm[I2]) { int II = nlop_get_nr_in_args(x); int OO = nlop_get_nr_out_args(x); assert(II == I2); PTR_ALLOC(struct nlop_s, n); const struct linop_s* (*der)[II][OO] = TYPE_ALLOC(const struct linop_s*[II][OO]); n->derivative = &(*der)[0][0]; for (int i = 0; i < II; i++) for (int o = 0; o < OO; o++) (*der)[i][o] = linop_clone(nlop_get_derivative(x, o, perm[i])); int perm2[II + OO]; for (int i = 0; i < II + OO; i++) perm2[i] = (i < OO) ? i : (OO + perm[i - OO]); n->op = operator_permute(operator_ref(x->op), II + OO, perm2); return PTR_PASS(n); } bart-0.5.00/src/nlops/chain.h000066400000000000000000000010311353046746100157050ustar00rootroot00000000000000 struct nlop_s; extern struct nlop_s* nlop_chain(const struct nlop_s* a, const struct nlop_s* b); extern struct nlop_s* nlop_chain_FF(const struct nlop_s* a, const struct nlop_s* b); extern struct nlop_s* nlop_chain2(const struct nlop_s* a, int o, const struct nlop_s* b, int i); extern struct nlop_s* nlop_combine(const struct nlop_s* a, const struct nlop_s* b); extern struct nlop_s* nlop_link(const struct nlop_s* x, int oo, int ii); extern struct nlop_s* nlop_permute_inputs(const struct nlop_s* x, int I2, const int perm[I2]); bart-0.5.00/src/nlops/nlop.c000066400000000000000000000316321353046746100156000ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include "num/multind.h" #include "num/ops.h" #include "num/iovec.h" #include "num/flpmath.h" #include "linops/linop.h" #include "misc/shrdptr.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/debug.h" #include "nlop.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif struct nlop_op_data_s { INTERFACE(operator_data_t); nlop_data_t* data; nlop_del_fun_t del; struct shared_ptr_s sptr; nlop_fun_t forward1; nlop_gen_fun_t forward; }; static DEF_TYPEID(nlop_op_data_s); struct nlop_linop_data_s { INTERFACE(linop_data_t); nlop_data_t* data; nlop_del_fun_t del; struct shared_ptr_s sptr; nlop_fun_t deriv; nlop_fun_t adjoint; nlop_fun_t normal; nlop_p_fun_t norm_inv; }; static DEF_TYPEID(nlop_linop_data_s); static void sptr_op_del(const struct shared_ptr_s* sptr) { auto data = CONTAINER_OF(sptr, struct nlop_op_data_s, sptr); data->del(data->data); } static void sptr_linop_del(const struct shared_ptr_s* sptr) { auto data = CONTAINER_OF(sptr, struct nlop_linop_data_s, sptr); data->del(data->data); } static void op_fun(const operator_data_t* _data, unsigned int N, void* args[__VLA(N)]) { auto data = CAST_DOWN(nlop_op_data_s, _data); if (NULL != data->forward1) { assert(2 == N); data->forward1(data->data, args[0], args[1]); } else { data->forward(data->data, N, *(complex float* (*)[N])args); } } static void op_del(const operator_data_t* _data) { auto data = CAST_DOWN(nlop_op_data_s, _data); shared_ptr_destroy(&data->sptr); xfree(data); } static void lop_der(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nlop_linop_data_s, _data); data->deriv(data->data, dst, src); } static void lop_adj(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nlop_linop_data_s, _data); data->adjoint(data->data, dst, src); } static void lop_nrm_inv(const linop_data_t* _data, float lambda, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nlop_linop_data_s, _data); data->norm_inv(data->data, lambda, dst, src); } static void lop_nrm(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nlop_linop_data_s, _data); data->normal(data->data, dst, src); } static void lop_del(const linop_data_t* _data) { auto data = CAST_DOWN(nlop_linop_data_s, _data); shared_ptr_destroy(&data->sptr); xfree(data); } struct nlop_s* nlop_generic_create2(int OO, int ON, const long odims[OO][ON], const long ostr[OO][ON], int II, int IN, const long idims[II][IN], const long istr[II][IN], nlop_data_t* data, nlop_gen_fun_t forward, nlop_fun_t deriv[II][OO], nlop_fun_t adjoint[II][OO], nlop_fun_t normal[II][OO], nlop_p_fun_t norm_inv[II][OO], nlop_del_fun_t del) { PTR_ALLOC(struct nlop_s, n); PTR_ALLOC(struct nlop_op_data_s, d); SET_TYPEID(nlop_op_data_s, d); d->data = data; d->forward1 = NULL; d->forward = forward; d->del = del; shared_ptr_init(&d->sptr, sptr_op_del); // n->op = operator_create2(ON, odims, ostrs, IN, idims, istrs, CAST_UP(PTR_PASS(d)), op_fun, op_del); unsigned int D[OO + II]; for (int i = 0; i < OO + II; i++) D[i] = (i < OO) ? ON : IN; const long* dims[OO + II]; for (int i = 0; i < OO + II; i++) dims[i] = (i < OO) ? odims[i] : idims[i - OO]; const long* strs[OO + II]; for (int i = 0; i < OO + II; i++) strs[i] = (i < OO) ? ostr[i] : istr[i - OO]; const struct linop_s* (*der)[II][OO] = TYPE_ALLOC(const struct linop_s*[II][OO]); n->derivative = &(*der)[0][0]; for (int i = 0; i < II; i++) { for (int o = 0; o < OO; o++) { PTR_ALLOC(struct nlop_linop_data_s, d2); SET_TYPEID(nlop_linop_data_s, d2); d2->data = data; d2->del = del; d2->deriv = deriv[i][o]; d2->adjoint = adjoint[i][o]; d2->normal = (NULL != normal) ? normal[i][o] : NULL; d2->norm_inv = (NULL != norm_inv) ? norm_inv[i][o] : NULL; shared_ptr_copy(&d2->sptr, &d->sptr); d2->sptr.del = sptr_linop_del; (*der)[i][o] = linop_create2(ON, odims[o], ostr[o], IN, idims[i], istr[i], CAST_UP(PTR_PASS(d2)), lop_der, lop_adj, (NULL != normal) ? lop_nrm : NULL, (NULL != norm_inv) ? lop_nrm_inv : NULL, lop_del); } } n->op = operator_generic_create2(OO + II, (1u << OO) - 1u, D, dims, strs, CAST_UP(PTR_PASS(d)), op_fun, op_del); return PTR_PASS(n); } struct nlop_s* nlop_create2(unsigned int ON, const long odims[__VLA(ON)], const long ostrs[__VLA(ON)], unsigned int IN, const long idims[__VLA(IN)], const long istrs[__VLA(IN)], nlop_data_t* data, nlop_fun_t forward, nlop_fun_t deriv, nlop_fun_t adjoint, nlop_fun_t normal, nlop_p_fun_t norm_inv, nlop_del_fun_t del) { struct nlop_s* op = nlop_generic_create2(1, ON, (const long(*)[])&odims[0], (const long(*)[])&ostrs[0], 1, IN, (const long(*)[])&idims[0], (const long(*)[])&istrs[0], data, NULL, (nlop_fun_t[1][1]){ { deriv } }, (nlop_fun_t[1][1]){ { adjoint } }, (NULL != normal) ? (nlop_fun_t[1][1]){ { normal } } : NULL, (NULL != norm_inv) ? (nlop_p_fun_t[1][1]){ { norm_inv } } : NULL, del); auto data2 = CAST_DOWN(nlop_op_data_s, operator_get_data(op->op)); data2->forward1 = forward; return op; } struct nlop_s* nlop_create(unsigned int ON, const long odims[__VLA(ON)], unsigned int IN, const long idims[__VLA(IN)], nlop_data_t* data, nlop_fun_t forward, nlop_fun_t deriv, nlop_fun_t adjoint, nlop_fun_t normal, nlop_p_fun_t norm_inv, nlop_del_fun_t del) { return nlop_create2( ON, odims, MD_STRIDES(ON, odims, CFL_SIZE), IN, idims, MD_STRIDES(IN, idims, CFL_SIZE), data, forward, deriv, adjoint, normal, norm_inv, del); } int nlop_get_nr_in_args(const struct nlop_s* op) { return operator_nr_in_args(op->op); } int nlop_get_nr_out_args(const struct nlop_s* op) { return operator_nr_out_args(op->op); } void nlop_free(const struct nlop_s* op) { int II = nlop_get_nr_in_args(op); int OO = nlop_get_nr_out_args(op); operator_free(op->op); const struct linop_s* (*der)[II][OO] = (void*)op->derivative; for (int i = 0; i < II; i++) for (int o = 0; o < OO; o++) linop_free((*der)[i][o]); xfree(der); xfree(op); } const struct nlop_s* nlop_clone(const struct nlop_s* op) { PTR_ALLOC(struct nlop_s, n); int II = nlop_get_nr_in_args(op); int OO = nlop_get_nr_out_args(op); n->op = operator_ref(op->op); const struct linop_s* (*der)[II][OO] = (void*)op->derivative; PTR_ALLOC(const struct linop_s*[II][OO], nder); for (int i = 0; i < II; i++) for (int o = 0; o < OO; o++) (*nder)[i][o] = linop_clone((*der)[i][o]); n->derivative = &(*PTR_PASS(nder))[0][0]; return PTR_PASS(n); } nlop_data_t* nlop_get_data(struct nlop_s* op) { auto data2 = CAST_DOWN(nlop_op_data_s, operator_get_data(op->op)); #if 1 auto data3 = CAST_DOWN(nlop_linop_data_s, linop_get_data(op->derivative[0])); assert(data3->data == data2->data); #endif return data2->data; } void nlop_apply(const struct nlop_s* op, int ON, const long odims[ON], complex float* dst, int IN, const long idims[IN], const complex float* src) { operator_apply(op->op, ON, odims, dst, IN, idims, src); } void nlop_derivative(const struct nlop_s* op, int ON, const long odims[ON], complex float* dst, int IN, const long idims[IN], const complex float* src) { assert(1 == nlop_get_nr_in_args(op)); assert(1 == nlop_get_nr_out_args(op)); linop_forward(nlop_get_derivative(op, 0, 0), ON, odims, dst, IN, idims, src); } void nlop_adjoint(const struct nlop_s* op, int ON, const long odims[ON], complex float* dst, int IN, const long idims[IN], const complex float* src) { assert(1 == nlop_get_nr_in_args(op)); assert(1 == nlop_get_nr_out_args(op)); linop_adjoint(nlop_get_derivative(op, 0, 0), ON, odims, dst, IN, idims, src); } void nlop_generic_apply_unchecked(const struct nlop_s* op, int N, void* args[N]) { operator_generic_apply_unchecked(op->op, N, args); } const struct linop_s* nlop_get_derivative(const struct nlop_s* op, int o, int i) { int II = nlop_get_nr_in_args(op); int OO = nlop_get_nr_out_args(op); assert((i < II) && (o < OO)); const struct linop_s* (*der)[II][OO] = (void*)op->derivative; return (*der)[i][o]; } const struct iovec_s* nlop_generic_domain(const struct nlop_s* op, int i) { return linop_domain(nlop_get_derivative(op, 0, i)); } const struct iovec_s* nlop_generic_codomain(const struct nlop_s* op, int o) { return linop_codomain(nlop_get_derivative(op, o, 0)); } const struct iovec_s* nlop_domain(const struct nlop_s* op) { assert(1 == nlop_get_nr_in_args(op)); assert(1 == nlop_get_nr_out_args(op)); return nlop_generic_domain(op, 0); } const struct iovec_s* nlop_codomain(const struct nlop_s* op) { assert(1 == nlop_get_nr_in_args(op)); assert(1 == nlop_get_nr_out_args(op)); return nlop_generic_codomain(op, 0); } struct flatten_s { INTERFACE(nlop_data_t); size_t* off; const struct nlop_s* op; }; DEF_TYPEID(flatten_s); static void flatten_fun(const nlop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(flatten_s, _data); int OO = nlop_get_nr_out_args(data->op); int II = nlop_get_nr_in_args(data->op); void* args[OO + II]; for (int o = 0; o < OO; o++) args[o] = (void*)dst + data->off[o]; for (int i = 0; i < II; i++) args[OO + i] = (void*)src + data->off[OO + i]; nlop_generic_apply_unchecked(data->op, OO + II, args); } static void flatten_der(const nlop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(flatten_s, _data); int OO = nlop_get_nr_out_args(data->op); int II = nlop_get_nr_in_args(data->op); for (int o = 0; o < OO; o++) { auto iov = linop_codomain(nlop_get_derivative(data->op, o, 0)); complex float* tmp = md_alloc_sameplace(iov->N, iov->dims, iov->size, src); md_clear(iov->N, iov->dims, (void*)dst + data->off[o], iov->size); for (int i = 0; i < II; i++) { const struct linop_s* der = nlop_get_derivative(data->op, o, i); auto iov2 = linop_domain(der); linop_forward(der, iov->N, iov->dims, tmp, iov2->N, iov2->dims, (void*)src + data->off[OO + i]); md_zadd(iov->N, iov->dims, (void*)dst + data->off[o], (void*)dst + data->off[o], tmp); } md_free(tmp); } } static void flatten_adj(const nlop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(flatten_s, _data); int OO = nlop_get_nr_out_args(data->op); int II = nlop_get_nr_in_args(data->op); for (int i = 0; i < II; i++) { auto iov = linop_domain(nlop_get_derivative(data->op, 0, i)); complex float* tmp = md_alloc_sameplace(iov->N, iov->dims, iov->size, src); md_clear(iov->N, iov->dims, (void*)dst + data->off[OO + i], iov->size); for (int o = 0; o < OO; o++) { // FIXME const struct linop_s* der = nlop_get_derivative(data->op, o, i); linop_adjoint_unchecked(der, tmp, (void*)src + data->off[o]); md_zadd(iov->N, iov->dims, (void*)dst + data->off[OO + i], (void*)dst + data->off[OO + i], tmp); } md_free(tmp); } } static void flatten_del(const nlop_data_t* _data) { auto data = CAST_DOWN(flatten_s, _data); nlop_free(data->op); xfree(data->off); xfree(data); } struct nlop_s* nlop_flatten(const struct nlop_s* op) { int II = nlop_get_nr_in_args(op); int OO = nlop_get_nr_out_args(op); long odims[1] = { 0 }; long ostrs[] = { CFL_SIZE }; size_t olast = 0; PTR_ALLOC(size_t[OO + II], offs); for (int o = 0; o < OO; o++) { auto iov = nlop_generic_codomain(op, o); assert(CFL_SIZE == iov->size); assert(iov->N == md_calc_blockdim(iov->N, iov->dims, iov->strs, iov->size)); odims[0] += md_calc_size(iov->N, iov->dims); (*offs)[o] = olast; olast = odims[0] * CFL_SIZE; } long idims[1] = { 0 }; long istrs[1] = { CFL_SIZE }; size_t ilast = 0; for (int i = 0; i < II; i++) { auto iov = nlop_generic_domain(op, i); assert(CFL_SIZE == iov->size); assert(iov->N == md_calc_blockdim(iov->N, iov->dims, iov->strs, iov->size)); idims[0] += md_calc_size(iov->N, iov->dims); (*offs)[OO + i] = ilast; ilast = idims[0] * CFL_SIZE; } PTR_ALLOC(struct flatten_s, data); SET_TYPEID(flatten_s, data); data->op = nlop_clone(op); data->off = *PTR_PASS(offs); return nlop_create2(1, odims, ostrs, 1, idims, istrs, CAST_UP(PTR_PASS(data)), flatten_fun, flatten_der, flatten_adj, NULL, NULL, flatten_del); } const struct nlop_s* nlop_flatten_get_op(struct nlop_s* op) { auto data = CAST_MAYBE(flatten_s, nlop_get_data(op)); return (NULL == data) ? NULL : data->op; } void nlop_debug(enum debug_levels dl, const struct nlop_s* x) { int II = nlop_get_nr_in_args(x); debug_printf(dl, "NLOP\ninputs: %d\n", II); for (int i = 0; i < II; i++) { auto io = nlop_generic_domain(x, i); debug_print_dims(dl, io->N, io->dims); } int OO = nlop_get_nr_out_args(x); debug_printf(dl, "outputs: %d\n", OO); for (int o = 0; o < OO; o++) { auto io = nlop_generic_codomain(x, o); debug_print_dims(dl, io->N, io->dims); } } bart-0.5.00/src/nlops/nlop.h000066400000000000000000000067531353046746100156130ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include "linops/linop.h" typedef struct nlop_data_s { TYPEID* TYPEID; } nlop_data_t; typedef void (*nlop_fun_t)(const nlop_data_t* _data, complex float* dst, const complex float* src); typedef void (*nlop_p_fun_t)(const nlop_data_t* _data, float lambda, complex float* dst, const complex float* src); typedef void (*nlop_del_fun_t)(const nlop_data_t* _data); typedef void (*nlop_gen_fun_t)(const nlop_data_t* _data, int N, complex float* arg[N]); struct operator_s; struct linop_s; struct nlop_s { const struct operator_s* op; const struct linop_s** derivative; }; extern struct nlop_s* nlop_generic_create(int O, int N, const long odims[O][N], int II, const long idims[II][N], nlop_data_t* data, nlop_gen_fun_t forward, nlop_fun_t deriv[II][O], nlop_fun_t adjoint[II][O], nlop_fun_t normal[II][O], nlop_p_fun_t norm_inv[II][O], nlop_del_fun_t del); extern struct nlop_s* nlop_generic_create2(int OO, int NO, const long odims[OO][NO], const long ostr[OO][NO], int II, int IN, const long idims[II][IN], const long istr[II][IN], nlop_data_t* data, nlop_gen_fun_t forward, nlop_fun_t deriv[II][OO], nlop_fun_t adjoint[II][OO], nlop_fun_t normal[II][OO], nlop_p_fun_t norm_inv[II][OO], nlop_del_fun_t del); extern struct nlop_s* nlop_create(unsigned int ON, const long odims[__VLA(ON)], unsigned int IN, const long idims[__VLA(IN)], nlop_data_t* data, nlop_fun_t forward, nlop_fun_t deriv, nlop_fun_t adjoint, nlop_fun_t normal, nlop_p_fun_t norm_inv, nlop_del_fun_t); extern struct nlop_s* nlop_create2(unsigned int ON, const long odims[__VLA(ON)], const long ostr[__VLA(ON)], unsigned int IN, const long idims[__VLA(IN)], const long istrs[__VLA(IN)], nlop_data_t* data, nlop_fun_t forward, nlop_fun_t deriv, nlop_fun_t adjoint, nlop_fun_t normal, nlop_p_fun_t norm_inv, nlop_del_fun_t); extern const struct nlop_s* nlop_clone(const struct nlop_s* op); extern void nlop_free(const struct nlop_s* op); extern nlop_data_t* nlop_get_data(struct nlop_s* op); extern int nlop_get_nr_in_args(const struct nlop_s* op); extern int nlop_get_nr_out_args(const struct nlop_s* op); extern void nlop_apply(const struct nlop_s* op, int ON, const long odims[ON], complex float* dst, int IN, const long idims[IN], const complex float* src); extern void nlop_derivative(const struct nlop_s* op, int ON, const long odims[ON], complex float* dst, int IN, const long idims[IN], const complex float* src); extern void nlop_adjoint(const struct nlop_s* op, int ON, const long odims[ON], complex float* dst, int IN, const long idims[IN], const complex float* src); extern void nlop_generic_apply_unchecked(const struct nlop_s* op, int N, void* args[N]); extern const struct linop_s* nlop_get_derivative(const struct nlop_s* op, int o, int i); extern const struct iovec_s* nlop_generic_domain(const struct nlop_s* op, int i); extern const struct iovec_s* nlop_generic_codomain(const struct nlop_s* op, int o); struct iovec_s; extern const struct iovec_s* nlop_domain(const struct nlop_s* op); extern const struct iovec_s* nlop_codomain(const struct nlop_s* op); extern struct nlop_s* nlop_flatten(const struct nlop_s* op); extern const struct nlop_s* nlop_flatten_get_op(struct nlop_s* op); enum debug_levels; extern void nlop_debug(enum debug_levels dl, const struct nlop_s* x); bart-0.5.00/src/nlops/nltest.c000066400000000000000000000041611353046746100161360ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include "misc/debug.h" #include "num/rand.h" #include "num/iovec.h" #include "num/multind.h" #include "num/flpmath.h" #if 1 #include "nlops/nlop.h" #include "nltest.h" float nlop_test_derivative(const struct nlop_s* op) { int N_dom = nlop_domain(op)->N; int N_cod = nlop_codomain(op)->N; long dims_dom[N_dom]; md_copy_dims(N_dom, dims_dom, nlop_domain(op)->dims); long dims_cod[N_cod]; md_copy_dims(N_cod, dims_cod, nlop_codomain(op)->dims); complex float* h = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* x1 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* x2 = md_alloc(N_dom, dims_dom, CFL_SIZE); complex float* d1 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* d2 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* d3 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* y1 = md_alloc(N_cod, dims_cod, CFL_SIZE); complex float* y2 = md_alloc(N_cod, dims_cod, CFL_SIZE); md_gaussian_rand(N_dom, dims_dom, x1); md_gaussian_rand(N_dom, dims_dom, h); nlop_apply(op, N_cod, dims_cod, y1, N_dom, dims_dom, x1); nlop_derivative(op, N_cod, dims_cod, d1, N_dom, dims_dom, h); float scale = 1.; float val0 = 0.; float val = 0.; float vall = 0.; for (int i = 0; i < 10; i++) { // d = F(x + s * h) - F(x) md_copy(N_dom, dims_dom, x2, x1, CFL_SIZE); md_zaxpy(N_dom, dims_dom, x2, scale, h); nlop_apply(op, N_cod, dims_cod, y2, N_dom, dims_dom, x2); md_zsub(N_cod, dims_cod, d2, y2, y1); // DF(s * h) md_zsmul(N_cod, dims_cod, d3, d1, scale); md_zsub(N_cod, dims_cod, d2, d2, d3); val = md_znorm(N_cod, dims_cod, d2); debug_printf(DP_DEBUG1, "%f/%f=%f\n", val, scale, val / scale); val /= scale; if ((0 == i) || (val > vall)) val0 = val; vall = val; scale /= 2.; } md_free(h); md_free(x1); md_free(x2); md_free(y1); md_free(y2); md_free(d1); md_free(d2); md_free(d3); return val / val0; } #endif bart-0.5.00/src/nlops/nltest.h000066400000000000000000000001151353046746100161360ustar00rootroot00000000000000 struct nlop_s; extern float nlop_test_derivative(const struct nlop_s* op); bart-0.5.00/src/nlops/tenmul.c000066400000000000000000000116161353046746100161340ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include "misc/types.h" #include "misc/misc.h" #include "num/multind.h" #include "num/flpmath.h" #include "nlops/nlop.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "tenmul.h" struct tenmul_s { INTERFACE(nlop_data_t); int N; const long* dims; const long* dims1; const long* dims2; const long* ostr; const long* istr1; const long* istr2; complex float* x1; complex float* x2; }; DEF_TYPEID(tenmul_s); static void tenmul_initialize(struct tenmul_s* data, const complex float* arg) { if (NULL == data->x1) data->x1 = md_alloc_sameplace(data->N, data->dims1, CFL_SIZE, arg); if (NULL == data->x2) data->x2 = md_alloc_sameplace(data->N, data->dims2, CFL_SIZE, arg); } static void tenmul_fun(const nlop_data_t* _data, int N, complex float* args[N]) { const auto data = CAST_DOWN(tenmul_s, _data); assert(3 == N); complex float* dst = args[0]; const complex float* src1 = args[1]; const complex float* src2 = args[2]; #ifdef USE_CUDA assert((cuda_ondevice(dst) == cuda_ondevice(src1)) && (cuda_ondevice(src1) == cuda_ondevice(src2))); #endif tenmul_initialize(data, dst); md_copy2(data->N, data->dims1, MD_STRIDES(data->N, data->dims1, CFL_SIZE), data->x1, data->istr1, src1, CFL_SIZE); md_copy2(data->N, data->dims2, MD_STRIDES(data->N, data->dims2, CFL_SIZE), data->x2, data->istr2, src2, CFL_SIZE); md_ztenmul2(data->N, data->dims, data->ostr, dst, data->istr1, src1, data->istr2, src2); } static void tenmul_der2(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(tenmul_s, _data); md_ztenmul2(data->N, data->dims, data->ostr, dst, data->istr2, src, MD_STRIDES(data->N, data->dims1, CFL_SIZE), data->x1); } static void tenmul_adj2(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(tenmul_s, _data); md_ztenmulc2(data->N, data->dims, data->istr2, dst, data->ostr, src, MD_STRIDES(data->N, data->dims1, CFL_SIZE), data->x1); } static void tenmul_der1(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(tenmul_s, _data); md_ztenmul2(data->N, data->dims, data->ostr, dst, data->istr1, src, MD_STRIDES(data->N, data->dims2, CFL_SIZE), data->x2); } static void tenmul_adj1(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(tenmul_s, _data); md_ztenmulc2(data->N, data->dims, data->istr1, dst, data->ostr, src, MD_STRIDES(data->N, data->dims2, CFL_SIZE), data->x2); } static void tenmul_del(const nlop_data_t* _data) { const auto data = CAST_DOWN(tenmul_s, _data); md_free(data->x1); md_free(data->x2); xfree(data->dims); xfree(data->ostr); xfree(data->dims1); xfree(data->istr1); xfree(data->dims2); xfree(data->istr2); xfree(data); } struct nlop_s* nlop_tenmul_create2(int N, const long dims[N], const long ostr[N], const long istr1[N], const long istr2[N]) { PTR_ALLOC(struct tenmul_s, data); SET_TYPEID(tenmul_s, data); PTR_ALLOC(long[N], ndims); md_copy_dims(N, *ndims, dims); PTR_ALLOC(long[N], nostr); md_copy_strides(N, *nostr, ostr); PTR_ALLOC(long[N], ndims1); PTR_ALLOC(long[N], nistr1); md_select_dims(N, md_nontriv_strides(N, istr1), *ndims1, dims); md_copy_strides(N, *nistr1, istr1); PTR_ALLOC(long[N], ndims2); PTR_ALLOC(long[N], nistr2); md_select_dims(N, md_nontriv_strides(N, istr2), *ndims2, dims); md_copy_strides(N, *nistr2, istr2); data->N = N; data->dims = *PTR_PASS(ndims); data->ostr = *PTR_PASS(nostr); data->dims1 = *PTR_PASS(ndims1); data->istr1 = *PTR_PASS(nistr1); data->dims2 = *PTR_PASS(ndims2); data->istr2 = *PTR_PASS(nistr2); // will be initialized later, to transparently support GPU data->x1 = NULL; data->x2 = NULL; long nl_odims[1][N]; md_select_dims(N, md_nontriv_strides(N, ostr), nl_odims[0], dims); long nl_ostr[1][N]; md_copy_strides(N, nl_ostr[0], ostr); long nl_idims[2][N]; md_copy_dims(N, nl_idims[0], data->dims1); md_copy_dims(N, nl_idims[1], data->dims2); long nl_istr[2][N]; md_copy_strides(N, nl_istr[0], istr1); md_copy_strides(N, nl_istr[1], istr2); return nlop_generic_create2(1, N, nl_odims, nl_ostr, 2, N, nl_idims, nl_istr, CAST_UP(PTR_PASS(data)), tenmul_fun, (nlop_fun_t[2][1]){ { tenmul_der1 }, { tenmul_der2 } }, (nlop_fun_t[2][1]){ { tenmul_adj1 }, { tenmul_adj2 } }, NULL, NULL, tenmul_del); } struct nlop_s* nlop_tenmul_create(int N, const long odim[N], const long idim1[N], const long idim2[N]) { long dims[N]; md_tenmul_dims(N, dims, odim, idim1, idim2); return nlop_tenmul_create2(N, dims, MD_STRIDES(N, odim, CFL_SIZE), MD_STRIDES(N, idim1, CFL_SIZE), MD_STRIDES(N, idim2, CFL_SIZE)); } bart-0.5.00/src/nlops/tenmul.h000066400000000000000000000003711353046746100161350ustar00rootroot00000000000000 struct nlop_s; struct nlop_s* nlop_tenmul_create2(int N, const long dims[N], const long dstr[N], const long istr1[N], const long istr[N]); struct nlop_s* nlop_tenmul_create(int N, const long odim[N], const long idim1[N], const long idims2[N]); bart-0.5.00/src/nlops/zexp.c000066400000000000000000000032541353046746100156150ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include "misc/types.h" #include "misc/misc.h" #include "num/multind.h" #include "num/flpmath.h" #include "nlops/nlop.h" #include "zexp.h" struct zexp_s { INTERFACE(nlop_data_t); int N; const long* dims; complex float* xn; }; DEF_TYPEID(zexp_s); static void zexp_fun(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(zexp_s, _data); md_zexp(data->N, data->dims, data->xn, src); md_copy(data->N, data->dims, dst, data->xn, CFL_SIZE); } static void zexp_der(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(zexp_s, _data); md_zmul(data->N, data->dims, dst, src, data->xn); } static void zexp_adj(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(zexp_s, _data); md_zmulc(data->N, data->dims, dst, src, data->xn); } static void zexp_del(const nlop_data_t* _data) { const auto data = CAST_DOWN(zexp_s, _data); md_free(data->xn); xfree(data->dims); xfree(data); } struct nlop_s* nlop_zexp_create(int N, const long dims[N]) { PTR_ALLOC(struct zexp_s, data); SET_TYPEID(zexp_s, data); PTR_ALLOC(long[N], ndims); md_copy_dims(N, *ndims, dims); data->N = N; data->dims = *PTR_PASS(ndims); data->xn = md_alloc(N, dims, CFL_SIZE); return nlop_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), zexp_fun, zexp_der, zexp_adj, NULL, NULL, zexp_del); } bart-0.5.00/src/nlops/zexp.h000066400000000000000000000001241353046746100156130ustar00rootroot00000000000000 struct nlop_s; extern struct nlop_s* nlop_zexp_create(int N, const long dims[N]); bart-0.5.00/src/noir/000077500000000000000000000000001353046746100142735ustar00rootroot00000000000000bart-0.5.00/src/noir/model.c000066400000000000000000000341031353046746100155400ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2017-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2011-2019 Martin Uecker * * * Uecker M, Hohage T, Block KT, Frahm J. Image reconstruction by regularized nonlinear * inversion – Joint estimation of coil sensitivities and image content. * Magn Reson Med 2008; 60:674-682. */ #include #include #include #include #include #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "linops/linop.h" #include "linops/someops.h" #include "linops/fmac.h" #include "nlops/nlop.h" #include "nlops/tenmul.h" #include "nlops/chain.h" #include "nlops/cast.h" #include "num/fft.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/filter.h" #include "model.h" struct noir_model_conf_s noir_model_conf_defaults = { .fft_flags = FFT_FLAGS, .cnstcoil_flags = TE_FLAG, .ptrn_flags = ~(COIL_FLAG|MAPS_FLAG), .rvc = false, .noncart = false, .a = 220., .b = 32., }; struct noir_op_s { INTERFACE(nlop_data_t); long dims[DIMS]; long data_dims[DIMS]; long coil_dims[DIMS]; long imgs_dims[DIMS]; const struct linop_s* weights; const struct linop_s* frw; const struct linop_s* adj; const struct nlop_s* nl; /*const*/ struct nlop_s* nl2; complex float* msk; complex float* wghts; complex float* ptr; complex float* adj_ptr; struct noir_model_conf_s conf; }; DEF_TYPEID(noir_op_s); static void noir_calc_weights(const struct noir_model_conf_s* conf, const long dims[3], complex float* dst) { unsigned int flags = 0; for (int i = 0; i < 3; i++) if (1 != dims[i]) flags = MD_SET(flags, i); klaplace(3, dims, flags, dst); md_zsmul(3, dims, dst, dst, conf->a); md_zsadd(3, dims, dst, dst, 1.); md_zspow(3, dims, dst, dst, -conf->b / 2.); // 1 + 220. \Laplace^16 } static struct noir_op_s* noir_init(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf) { PTR_ALLOC(struct noir_op_s, data); SET_TYPEID(noir_op_s, data); data->conf = *conf; md_copy_dims(DIMS, data->dims, dims); md_select_dims(DIMS, ~conf->cnstcoil_flags, data->coil_dims, dims); md_select_dims(DIMS, ~COIL_FLAG, data->imgs_dims, dims); md_select_dims(DIMS, ~MAPS_FLAG, data->data_dims, dims); long mask_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS, mask_dims, dims); long wght_dims[DIMS]; md_select_dims(DIMS, FFT_FLAGS, wght_dims, dims); long ptrn_dims[DIMS]; md_select_dims(DIMS, conf->ptrn_flags, ptrn_dims, dims); data->wghts = md_alloc(DIMS, wght_dims, CFL_SIZE); noir_calc_weights(conf, dims, data->wghts); fftmod(DIMS, wght_dims, FFT_FLAGS, data->wghts, data->wghts); fftscale(DIMS, wght_dims, FFT_FLAGS, data->wghts, data->wghts); const struct linop_s* wghts = linop_cdiag_create(DIMS, data->coil_dims, FFT_FLAGS, data->wghts); const struct linop_s* wghts_ifft = linop_ifft_create(DIMS, data->coil_dims, FFT_FLAGS); data->weights = linop_chain(wghts, wghts_ifft); linop_free(wghts); linop_free(wghts_ifft); const struct linop_s* lop_fft = linop_fft_create(DIMS, data->data_dims, conf->fft_flags); data->ptr = md_alloc(DIMS, ptrn_dims, CFL_SIZE); md_copy(DIMS, ptrn_dims, data->ptr, psf, CFL_SIZE); fftmod(DIMS, ptrn_dims, conf->fft_flags, data->ptr, data->ptr); const struct linop_s* lop_pattern = linop_fmac_create(DIMS, data->data_dims, 0, 0, COIL_FLAG, data->ptr); const struct linop_s* lop_adj_pattern; if (!conf->noncart) { lop_adj_pattern = linop_clone(lop_pattern); data->adj_ptr = NULL; } else { data->adj_ptr = md_alloc(DIMS, ptrn_dims, CFL_SIZE); md_zfill(DIMS, ptrn_dims, data->adj_ptr, 1.); fftmod(DIMS, ptrn_dims, conf->fft_flags, data->adj_ptr, data->adj_ptr); lop_adj_pattern = linop_fmac_create(DIMS, data->data_dims, 0, 0, COIL_FLAG, data->adj_ptr); } data->msk = md_alloc(DIMS, mask_dims, CFL_SIZE); if (NULL == mask) { md_zfill(DIMS, mask_dims, data->msk, 1.); } else { md_copy(DIMS, mask_dims, data->msk, mask, CFL_SIZE); } fftscale(DIMS, mask_dims, FFT_FLAGS, data->msk, data->msk); const struct linop_s* lop_mask = linop_cdiag_create(DIMS, data->data_dims, FFT_FLAGS, data->msk); const struct linop_s* lop_fft2 = linop_chain(lop_mask, lop_fft); linop_free(lop_mask); linop_free(lop_fft); data->frw = linop_chain(lop_fft2, lop_pattern); linop_free(lop_pattern); data->adj = linop_chain(lop_fft2, lop_adj_pattern); linop_free(lop_fft2); linop_free(lop_adj_pattern); const struct nlop_s* nlw1 = nlop_tenmul_create(DIMS, data->data_dims, data->imgs_dims, data->coil_dims); const struct nlop_s* nlw2 = nlop_from_linop(data->weights); data->nl = nlop_chain2(nlw2, 0, nlw1, 1); nlop_free(nlw1); nlop_free(nlw2); const struct nlop_s* frw = nlop_from_linop(data->frw); data->nl2 = nlop_chain2(data->nl, 0, frw, 0); nlop_free(frw); return PTR_PASS(data); } static void noir_free(struct noir_op_s* data) { md_free(data->ptr); md_free(data->adj_ptr); md_free(data->wghts); md_free(data->msk); linop_free(data->frw); linop_free(data->adj); linop_free(data->weights); nlop_free(data->nl); nlop_free(data->nl2); xfree(data); } static void noir_del(const nlop_data_t* _data) { noir_free(CAST_DOWN(noir_op_s, _data)); } void noir_forw_coils(const struct linop_s* op, complex float* dst, const complex float* src) { linop_forward_unchecked(op, dst, src); } void noir_back_coils(const struct linop_s* op, complex float* dst, const complex float* src) { linop_adjoint_unchecked(op, dst, src); } static void noir_fun2(const nlop_data_t* _data, int N, complex float* args[N]) { const auto data = CAST_DOWN(noir_op_s, _data); void* args2[3] = { args[0], args[1], args[2] }; nlop_generic_apply_unchecked(data->nl2, 3, args2); } static void noir_fun(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); long split = md_calc_size(DIMS, data->imgs_dims); noir_fun2(_data, 3, (complex float*[3]){ dst, (complex float*)src, (complex float*)(src + split) }); } static void noir_derA(const nlop_data_t* _data, complex float* dst, const complex float* img) { const auto data = CAST_DOWN(noir_op_s, _data); auto der1 = nlop_get_derivative(data->nl, 0, 0); linop_forward(der1, DIMS, data->data_dims, dst, DIMS, data->imgs_dims, img); } static void noir_derB(const nlop_data_t* _data, complex float* dst, const complex float* coils) { const auto data = CAST_DOWN(noir_op_s, _data); auto der2 = nlop_get_derivative(data->nl, 0, 1); linop_forward(der2, DIMS, data->data_dims, dst, DIMS, data->coil_dims, coils); } static void noir_derA2(const nlop_data_t* _data, complex float* dst, const complex float* img) { const auto data = CAST_DOWN(noir_op_s, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, dst); noir_derA(_data, tmp, img); linop_forward(data->frw, DIMS, data->data_dims, dst, DIMS, data->data_dims, tmp); md_free(tmp); } static void noir_derB2(const nlop_data_t* _data, complex float* dst, const complex float* coils) { const auto data = CAST_DOWN(noir_op_s, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, dst); noir_derB(_data, tmp, coils); linop_forward(data->frw, DIMS, data->data_dims, dst, DIMS, data->data_dims, tmp); md_free(tmp); } static void noir_der2(const nlop_data_t* _data, complex float* dst, const complex float* img, const complex float* coils) { const auto data = CAST_DOWN(noir_op_s, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, img); noir_derA(_data, tmp, img); complex float* tmp2 = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, img); noir_derB(_data, tmp2, coils); md_zadd(DIMS, data->data_dims, tmp, tmp, tmp2); md_free(tmp2); linop_forward(data->frw, DIMS, data->data_dims, dst, DIMS, data->data_dims, tmp); md_free(tmp); } static void noir_der(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); long split = md_calc_size(DIMS, data->imgs_dims); noir_der2(_data, dst, src, src + split); } static void noir_adjA(const nlop_data_t* _data, complex float* img, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); auto der1 = nlop_get_derivative(data->nl, 0, 0); linop_adjoint(der1, DIMS, data->imgs_dims, img, DIMS, data->data_dims, src); if (data->conf.rvc) md_zreal(DIMS, data->imgs_dims, img, img); } static void noir_adjB(const nlop_data_t* _data, complex float* coils, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); auto der2 = nlop_get_derivative(data->nl, 0, 1); linop_adjoint(der2, DIMS, data->coil_dims, coils, DIMS, data->data_dims, src); } static void noir_adjA2(const nlop_data_t* _data, complex float* img, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, img); linop_adjoint(data->adj, DIMS, data->data_dims, tmp, DIMS, data->data_dims, src); noir_adjA(_data, img, tmp); md_free(tmp); } static void noir_adjB2(const nlop_data_t* _data, complex float* coils, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, coils); linop_adjoint(data->adj, DIMS, data->data_dims, tmp, DIMS, data->data_dims, src); noir_adjB(_data, coils, tmp); md_free(tmp); } static void noir_adj2(const nlop_data_t* _data, complex float* img, complex float* coils, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); complex float* tmp = md_alloc_sameplace(DIMS, data->data_dims, CFL_SIZE, img); linop_adjoint(data->adj, DIMS, data->data_dims, tmp, DIMS, data->data_dims, src); noir_adjB(_data, coils, tmp); noir_adjA(_data, img, tmp); md_free(tmp); } static void noir_adj(const nlop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(noir_op_s, _data); long split = md_calc_size(DIMS, data->imgs_dims); noir_adj2(_data, dst, dst + split, src); } struct noir_s noir_create3(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf) { struct noir_op_s* data = noir_init(dims, mask, psf, conf); long idims[DIMS]; md_select_dims(DIMS, ~COIL_FLAG, idims, dims); long odims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, odims, dims); long cdims[DIMS]; md_select_dims(DIMS, ~conf->cnstcoil_flags, cdims, dims); long nl_odims[1][DIMS]; md_copy_dims(DIMS, nl_odims[0], odims); long nl_ostr[1][DIMS]; md_calc_strides(DIMS, nl_ostr[0], odims, CFL_SIZE); long nl_idims[2][DIMS]; md_copy_dims(DIMS, nl_idims[0], idims); md_copy_dims(DIMS, nl_idims[1], cdims); long nl_istr[2][DIMS]; md_calc_strides(DIMS, nl_istr[0], idims, CFL_SIZE); md_calc_strides(DIMS, nl_istr[1], cdims, CFL_SIZE); struct noir_s ret = { .linop = data->weights, .noir_op = data }; ret.nlop = nlop_generic_create2(1, DIMS, nl_odims, nl_ostr, 2, DIMS, nl_idims, nl_istr, CAST_UP(PTR_PASS(data)), noir_fun2, (nlop_fun_t[2][1]){ { noir_derA2 }, { noir_derB2 } }, (nlop_fun_t[2][1]){ { noir_adjA2 }, { noir_adjB2 } }, NULL, NULL, noir_del); return ret; } struct noir_s noir_create2(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf) { assert(!conf->noncart); assert(!conf->rvc); struct noir_op_s* data = noir_init(dims, mask, psf, conf); struct nlop_s* nlop = data->nl2; return (struct noir_s){ .nlop = nlop, .linop = data->weights, .noir_op = data }; } struct noir_s noir_create(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf) { #if 1 struct noir_op_s* data = noir_init(dims, mask, psf, conf); long idims[DIMS]; md_select_dims(DIMS, ~(COIL_FLAG|conf->cnstcoil_flags), idims, dims); long edims[DIMS]; md_select_dims(DIMS, conf->cnstcoil_flags, edims, dims); idims[COIL_DIM] = dims[COIL_DIM] + md_calc_size(DIMS, edims); // add images long odims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, odims, dims); struct noir_s ret = { .linop = data->weights, .noir_op = data }; ret.nlop = nlop_create(DIMS, odims, DIMS, idims, CAST_UP(PTR_PASS(data)), noir_fun, noir_der, noir_adj, NULL, NULL, noir_del); return ret; #else // less efficient than the manuel coded functions struct noir_s ret = noir_create2(dims, mask, psf, conf); ret.nlop = nlop_flatten(ret.nlop); return ret; #endif } __attribute__((optimize("-fno-finite-math-only"))) static void proj_add(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long v1_strs[D], complex float* v1, const long v2_strs[D], complex float* v2) { float v22 = md_zscalar_real2(D, dims, v2_strs, v2, v2_strs, v2); // since it is real anyway complex float v12 = md_zscalar2(D, dims, v1_strs, v1, v2_strs, v2) / v22; if (!isfinite(crealf(v12)) || !isfinite(cimagf(v12))) v12 = 0.; md_zaxpy2(D, dims, ostrs, optr, v12, v2_strs, v2); } // FIXME: review dimensions void noir_orthogonalize(struct noir_s* op, complex float* coils) { struct noir_op_s* data = op->noir_op; // orthogonalization of the coil profiles long nmaps = data->imgs_dims[MAPS_DIM]; if (1L == nmaps) return; long single_map_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, single_map_dims, data->dims); long single_map_strs[DIMS]; md_calc_strides(DIMS, single_map_strs, single_map_dims, CFL_SIZE); long data_strs[DIMS]; md_calc_strides(DIMS, data_strs, data->dims, CFL_SIZE); complex float* tmp = md_alloc_sameplace(DIMS, single_map_dims, CFL_SIZE, coils); for (long map = 0L; map < nmaps; ++map) { complex float* map_ptr = (void*)coils + map * data_strs[MAPS_DIM]; md_clear(DIMS, single_map_dims, tmp, CFL_SIZE); for (long prev = 0L; prev < map; ++prev) { complex float* prev_map_ptr = (void*)coils + prev * data_strs[MAPS_DIM]; proj_add(DIMS, single_map_dims, single_map_strs, tmp, single_map_strs, map_ptr, data_strs, prev_map_ptr); } md_zsub2(DIMS, single_map_dims, data_strs, map_ptr, data_strs, map_ptr, single_map_strs, tmp); } md_free(tmp); } bart-0.5.00/src/noir/model.h000066400000000000000000000024471353046746100155530ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/mri.h" struct linop_s; extern void noir_forw_coils(const struct linop_s* op, complex float* dst, const complex float* src); extern void noir_back_coils(const struct linop_s* op, complex float* dst, const complex float* src); struct noir_model_conf_s { unsigned int fft_flags; unsigned int cnstcoil_flags; unsigned int ptrn_flags; _Bool rvc; _Bool noncart; float a; float b; }; extern struct noir_model_conf_s noir_model_conf_defaults; struct nlop_s; struct noir_s { struct nlop_s* nlop; const struct linop_s* linop; struct noir_op_s* noir_op; }; extern struct noir_s noir_create2(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf); extern struct noir_s noir_create(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf); extern struct noir_s noir_create3(const long dims[DIMS], const complex float* mask, const complex float* psf, const struct noir_model_conf_s* conf); struct nlop_data_s; extern void noir_orthogonalize(struct noir_s* op, complex float* coils); bart-0.5.00/src/noir/recon.c000066400000000000000000000100711353046746100155440ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2011-2018 Martin Uecker * * * Uecker M, Hohage T, Block KT, Frahm J. Image reconstruction by regularized * nonlinear inversion – Joint estimation of coil sensitivities and image content. * Magn Reson Med 2008; 60:674-682. */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "iter/iter3.h" #include "iter/iter4.h" #include "iter/thresh.h" #include "iter/italgos.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/mri.h" #include "misc/debug.h" #include "misc/mmio.h" #include "noir/model.h" #include "nlops/nlop.h" #include "recon.h" struct nlop_wrapper_s { INTERFACE(struct iter_op_data_s); struct noir_s* noir; long split; }; DEF_TYPEID(nlop_wrapper_s); static void orthogonalize(iter_op_data* ptr, float* _dst, const float* _src) { #if 0 noir_orthogonalize(nlop_get_data(CAST_DOWN(nlop_wrapper_s, ptr)->noir), (complex float*)_dst, (const complex float*)_src); #else UNUSED(_src); auto nlw = CAST_DOWN(nlop_wrapper_s, ptr); noir_orthogonalize(nlw->noir, (complex float*) _dst + nlw->split); #endif } const struct noir_conf_s noir_defaults = { .iter = 8, .rvc = false, .noncart = false, .alpha = 1., .alpha_min = 0., .redu = 2., .a = 220., .b = 32., .pattern_for_each_coil = false, .sms = false, }; void noir_recon(const struct noir_conf_s* conf, const long dims[DIMS], complex float* img, complex float* sens, complex float* ksens, const complex float* ref, const complex float* pattern, const complex float* mask, const complex float* kspace_data ) { struct noir_model_conf_s mconf = noir_model_conf_defaults; mconf.rvc = conf->rvc; mconf.noncart = conf->noncart; mconf.fft_flags = FFT_FLAGS; mconf.a = conf->a; mconf.b = conf->b; mconf.ptrn_flags = ~(MAPS_FLAG|COIL_FLAG); if (conf->sms) mconf.fft_flags |= SLICE_FLAG; if (conf->pattern_for_each_coil) mconf.ptrn_flags |= COIL_FLAG; long imgs_dims[DIMS]; long coil_dims[DIMS]; long data_dims[DIMS]; md_select_dims(DIMS, ~COIL_FLAG, imgs_dims, dims); md_select_dims(DIMS, ~mconf.cnstcoil_flags, coil_dims, dims); md_select_dims(DIMS, ~MAPS_FLAG, data_dims, dims); long skip = md_calc_size(DIMS, imgs_dims); long size = skip + md_calc_size(DIMS, coil_dims); long data_size = md_calc_size(DIMS, data_dims); long d1[1] = { size }; // variable which is optimized by the IRGNM complex float* x = md_alloc_sameplace(1, d1, CFL_SIZE, kspace_data); md_copy(DIMS, imgs_dims, x, img, CFL_SIZE); md_copy(DIMS, coil_dims, x + skip, ksens, CFL_SIZE); complex float* xref = NULL; if (NULL != ref) { xref = md_alloc_sameplace(1, d1, CFL_SIZE, kspace_data); md_copy(1, d1, xref, ref, CFL_SIZE); } #if 1 struct noir_s nl = noir_create(dims, mask, pattern, &mconf); #else struct noir_s nl = noir_create3(dims, mask, pattern, &mconf); nl.nlop = nlop_flatten(nl.nlop); #endif struct iter3_irgnm_conf irgnm_conf = iter3_irgnm_defaults; irgnm_conf.iter = conf->iter; irgnm_conf.alpha = conf->alpha; irgnm_conf.alpha_min = conf->alpha_min; irgnm_conf.redu = conf->redu; irgnm_conf.cgtol = 0.1f; irgnm_conf.nlinv_legacy = true; irgnm_conf.alpha_min = conf->alpha_min; struct nlop_wrapper_s nlw; SET_TYPEID(nlop_wrapper_s, &nlw); nlw.noir = &nl; nlw.split = skip; iter4_irgnm(CAST_UP(&irgnm_conf), nl.nlop, size * 2, (float*)x, (const float*)xref, data_size * 2, (const float*)kspace_data, NULL, (struct iter_op_s){ orthogonalize, CAST_UP(&nlw) }); md_copy(DIMS, imgs_dims, img, x, CFL_SIZE); md_copy(DIMS, coil_dims, ksens, x + skip, CFL_SIZE); noir_forw_coils(nl.linop, x + skip, x + skip); md_copy(DIMS, coil_dims, sens, x + skip, CFL_SIZE); // needed for GPU fftmod(DIMS, coil_dims, mconf.fft_flags, sens, sens); nlop_free(nl.nlop); md_free(x); md_free(xref); } bart-0.5.00/src/noir/recon.h000066400000000000000000000015561353046746100155610ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" #include "misc/mri.h" struct noir_conf_s { unsigned int iter; _Bool rvc; _Bool noncart; float alpha; float alpha_min; float redu; float a; float b; _Bool pattern_for_each_coil; _Bool sms; }; extern const struct noir_conf_s noir_defaults; extern void noir_recon(const struct noir_conf_s* conf, const long dims[DIMS], _Complex float* img, _Complex float* sens, _Complex float* ksens, const _Complex float* ref, const _Complex float* pattern, const _Complex float* mask, const _Complex float* kspace_data); #include "misc/cppwrap.h" bart-0.5.00/src/noise.c000066400000000000000000000032371353046746100146120ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * 2013 Jonathan Tamir */ #include #include #include #include "num/multind.h" #include "num/rand.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Add noise with selected variance to input."; int main_noise(int argc, char* argv[]) { float var = 1.; float spike = 1.; bool rvc = false; int rinit = -1; const struct opt_s opts[] = { OPT_INT('s', &rinit, "", "random seed initialization"), OPT_FLOAT('S', &spike, "", "()"), OPT_SET('r', &rvc, "real-valued input"), OPT_FLOAT('n', &var, "variance", "DEFAULT: 1.0"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); if (-1 != rinit) num_rand_init(rinit); unsigned int N = DIMS; long dims[N]; complex float* y = load_cfl(argv[1], N, dims); complex float* x = create_cfl(argv[2], N, dims); long T = md_calc_size(N, dims); // scale var for complex data if (!rvc) var = var / 2.f; float stdev = sqrtf(var); for (long i = 0; i < T; i++) { x[i] = y[i]; if (spike >= uniform_rand()) x[i] += stdev * gaussian_rand(); if (rvc) x[i] = crealf(x[i]); } unmap_cfl(N, dims, y); unmap_cfl(N, dims, x); return 0; } bart-0.5.00/src/noncart/000077500000000000000000000000001353046746100147705ustar00rootroot00000000000000bart-0.5.00/src/noncart/grid.c000066400000000000000000000227011353046746100160630ustar00rootroot00000000000000/* Copyright 2014-2015 The Regents of the University of California. * Copyright 2015-2019 Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2011-2019 Martin Uecker * 2014 Frank Ong */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/specfun.h" #include "misc/nested.h" #include "misc/misc.h" #include "grid.h" static double kb(double beta, double x) { if (fabs(x) >= 0.5) return 0.; return bessel_i0(beta * sqrt(1. - pow(2. * x, 2.))) / bessel_i0(beta); } static void kb_precompute(double beta, int n, float table[n + 1]) { for (int i = 0; i < n + 1; i++) table[i] = kb(beta, (double)(i) / (double)(n - 1) / 2.); } static double ftkb(double beta, double x) { double a = sqrt(pow(beta, 2.) - pow(M_PI * x, 2.)); return ((0. == a) ? 1. : (a / sinh(a))); // * bessel_i0(beta); } static double rolloff(double x, double beta, double width) { return ftkb(beta, x * width) / ftkb(beta, 0.); } // Linear interpolation static float lerp(float a, float b, float c) { return (1. - c) * a + c * b; } // Linear interpolation look up static float intlookup(int n, const float table[n + 1], float x) { float fpart; // fpart = modff(x * n, &ipart); // int index = ipart; int index = (int)(x * (n - 1)); fpart = x * (n - 1) - (float)index; #if 1 assert(index >= 0); assert(index <= n); assert(fpart >= 0.); assert(fpart <= 1.); #endif float l = lerp(table[index], table[index + 1], fpart); #if 1 assert(l <= 1.); assert(0 >= 0.); #endif return l; } enum { kb_size = 100 }; static float kb_table[kb_size + 1]; static float kb_beta = -1.; void gridH(const struct grid_conf_s* conf, const complex float* traj, const long ksp_dims[4], complex float* dst, const long grid_dims[4], const complex float* grid) { long C = ksp_dims[3]; // precompute kaiser bessel table #pragma omp critical if (-1 == kb_beta) { kb_precompute(conf->beta, kb_size, kb_table); kb_beta = conf->beta; } assert(fabs(kb_beta - conf->beta) < 1.E-6); assert(1 == ksp_dims[0]); long samples = ksp_dims[1] * ksp_dims[2]; #pragma omp parallel for for(int i = 0; i < samples; i++) { float pos[3]; pos[0] = conf->os * (creal(traj[i * 3 + 0])); pos[1] = conf->os * (creal(traj[i * 3 + 1])); pos[2] = conf->os * (creal(traj[i * 3 + 2])); pos[0] += (grid_dims[0] > 1) ? ((float)grid_dims[0] / 2.) : 0.; pos[1] += (grid_dims[1] > 1) ? ((float)grid_dims[1] / 2.) : 0.; pos[2] += (grid_dims[2] > 1) ? ((float)grid_dims[2] / 2.) : 0.; complex float val[C]; for (int j = 0; j < C; j++) val[j] = 0.0; grid_pointH(C, 3, grid_dims, pos, val, grid, conf->periodic, conf->width, kb_size, kb_table); for (int j = 0; j < C; j++) dst[j * samples + i] += val[j]; } } void grid(const struct grid_conf_s* conf, const complex float* traj, const long grid_dims[4], complex float* grid, const long ksp_dims[4], const complex float* src) { long C = ksp_dims[3]; // precompute kaiser bessel table #pragma omp critical if (-1 == kb_beta) { kb_precompute(conf->beta, kb_size, kb_table); kb_beta = conf->beta; } assert(fabs(kb_beta - conf->beta) < 1.E-6); assert(1 == ksp_dims[0]); long samples = ksp_dims[1] * ksp_dims[2]; // grid #pragma omp parallel for for(int i = 0; i < samples; i++) { float pos[3]; pos[0] = conf->os * (creal(traj[i * 3 + 0])); pos[1] = conf->os * (creal(traj[i * 3 + 1])); pos[2] = conf->os * (creal(traj[i * 3 + 2])); pos[0] += (grid_dims[0] > 1) ? ((float) grid_dims[0] / 2.) : 0.; pos[1] += (grid_dims[1] > 1) ? ((float) grid_dims[1] / 2.) : 0.; pos[2] += (grid_dims[2] > 1) ? ((float) grid_dims[2] / 2.) : 0.; complex float val[C]; for (int j = 0; j < C; j++) val[j] = src[j * samples + i]; grid_point(C, 3, grid_dims, pos, grid, val, conf->periodic, conf->width, kb_size, kb_table); } } static void grid2_dims(unsigned int D, const long trj_dims[D], const long ksp_dims[D], const long grid_dims[D]) { assert(D >= 4); assert(md_check_compat(D - 3, ~0, grid_dims + 3, ksp_dims + 3)); // assert(md_check_compat(D - 3, ~(MD_BIT(0) | MD_BIT(1)), trj_dims + 3, ksp_dims + 3)); assert(md_check_bounds(D - 3, ~0, trj_dims + 3, ksp_dims + 3)); assert(3 == trj_dims[0]); assert(1 == trj_dims[3]); assert(1 == ksp_dims[0]); } void grid2(const struct grid_conf_s* conf, unsigned int D, const long trj_dims[D], const complex float* traj, const long grid_dims[D], complex float* dst, const long ksp_dims[D], const complex float* src) { grid2_dims(D, trj_dims, ksp_dims, grid_dims); long ksp_strs[D]; md_calc_strides(D, ksp_strs, ksp_dims, CFL_SIZE); long trj_strs[D]; md_calc_strides(D, trj_strs, trj_dims, CFL_SIZE); long grid_strs[D]; md_calc_strides(D, grid_strs, grid_dims, CFL_SIZE); long pos[D]; for (unsigned int i = 0; i < D; i++) pos[i] = 0; do { grid(conf, &MD_ACCESS(D, trj_strs, pos, traj), grid_dims, &MD_ACCESS(D, grid_strs, pos, dst), ksp_dims, &MD_ACCESS(D, ksp_strs, pos, src)); } while(md_next(D, ksp_dims, (~0 ^ 15), pos)); } void grid2H(const struct grid_conf_s* conf, unsigned int D, const long trj_dims[D], const complex float* traj, const long ksp_dims[D], complex float* dst, const long grid_dims[D], const complex float* src) { grid2_dims(D, trj_dims, ksp_dims, grid_dims); long ksp_strs[D]; md_calc_strides(D, ksp_strs, ksp_dims, CFL_SIZE); long trj_strs[D]; md_calc_strides(D, trj_strs, trj_dims, CFL_SIZE); long grid_strs[D]; md_calc_strides(D, grid_strs, grid_dims, CFL_SIZE); long pos[D]; for (unsigned int i = 0; i < D; i++) pos[i] = 0; do { gridH(conf, &MD_ACCESS(D, trj_strs, pos, traj), ksp_dims, &MD_ACCESS(D, ksp_strs, pos, dst), grid_dims, &MD_ACCESS(D, grid_strs, pos, src)); } while(md_next(D, ksp_dims, (~0 ^ 15), pos)); } typedef void CLOSURE_TYPE(grid_update_t)(long ind, float d); #ifndef __clang__ #define VLA(x) x #else // blocks extension does not play well even with arguments which // just look like variably-modified types #define VLA(x) #endif static void grid_point_gen(int N, const long dims[VLA(N)], const float pos[VLA(N)], bool periodic, float width, int kb_size, const float kb_table[VLA(kb_size + 1)], grid_update_t update) { #ifndef __clang__ int sti[N]; int eni[N]; int off[N]; #else // blocks extension does not play well with variably-modified types int* sti = alloca(sizeof(int[N])); int* eni = alloca(sizeof(int[N])); int* off = alloca(sizeof(int[N])); #endif for (int j = 0; j < N; j++) { sti[j] = (int)ceil(pos[j] - width); eni[j] = (int)floor(pos[j] + width); off[j] = 0; if (sti[j] > eni[j]) return; if (!periodic) { sti[j] = MAX(sti[j], 0); eni[j] = MIN(eni[j], dims[j] - 1); } else { while (sti[j] + off[j] < 0) off[j] += dims[j]; } if (1 == dims[j]) { assert(0. == pos[j]); // ==0. fails nondeterministically for test_nufft_forward bbdec08cb sti[j] = 0; eni[j] = 0; } } __block NESTED(void, grid_point_r, (int N, long ind, float d)) // __block for recursion { if (0 == N) { NESTED_CALL(update, (ind, d)); } else { N--; for (int w = sti[N]; w <= eni[N]; w++) { float frac = fabs(((float)w - pos[N])); float d2 = d * intlookup(kb_size, kb_table, frac / width); long ind2 = (ind * dims[N] + ((w + off[N]) % dims[N])); grid_point_r(N, ind2, d2); } } }; grid_point_r(N, 0, 1.); } void grid_point(unsigned int ch, int N, const long dims[VLA(N)], const float pos[VLA(N)], complex float* dst, const complex float val[VLA(ch)], bool periodic, float width, int kb_size, const float kb_table[kb_size + 1]) { NESTED(void, update, (long ind, float d)) { for (unsigned int c = 0; c < ch; c++) { // we are allowed to update real and imaginary part independently which works atomically #pragma omp atomic __real(dst[ind + c * dims[0] * dims[1] * dims[2]]) += __real(val[c]) * d; #pragma omp atomic __imag(dst[ind + c * dims[0] * dims[1] * dims[2]]) += __imag(val[c]) * d; } }; grid_point_gen(N, dims, pos, periodic, width, kb_size, kb_table, update); } void grid_pointH(unsigned int ch, int N, const long dims[VLA(N)], const float pos[VLA(N)], complex float val[VLA(ch)], const complex float* src, bool periodic, float width, int kb_size, const float kb_table[kb_size + 1]) { NESTED(void, update, (long ind, float d)) { for (unsigned int c = 0; c < ch; c++) { // we are allowed to update real and imaginary part independently which works atomically #pragma omp atomic __real(val[c]) += __real(src[ind + c * dims[0] * dims[1] * dims[2]]) * d; #pragma omp atomic __imag(val[c]) += __imag(src[ind + c * dims[0] * dims[1] * dims[2]]) * d; } }; grid_point_gen(N, dims, pos, periodic, width, kb_size, kb_table, update); } double calc_beta(float os, float width) { return M_PI * sqrt(pow((width * 2. / os) * (os - 0.5), 2.) - 0.8); } static float pos(int d, int i) { return (1 == d) ? 0. : (((float)i - (float)d / 2.) / (float)d); } void rolloff_correction(float os, float width, float beta, const long dimensions[3], complex float* dst) { UNUSED(os); #pragma omp parallel for collapse(3) for (int z = 0; z < dimensions[2]; z++) for (int y = 0; y < dimensions[1]; y++) for (int x = 0; x < dimensions[0]; x++) dst[x + dimensions[0] * (y + z * dimensions[1])] = rolloff(pos(dimensions[0], x), beta, width) * rolloff(pos(dimensions[1], y), beta, width) * rolloff(pos(dimensions[2], z), beta, width); } bart-0.5.00/src/noncart/grid.h000066400000000000000000000034421353046746100160710ustar00rootroot00000000000000/* Copyright 2014-2015 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include "misc/cppwrap.h" struct grid_conf_s { float os; float width; _Bool periodic; double beta; }; extern void grid(const struct grid_conf_s* conf, const complex float* traj, const long grid_dims[4], complex float* grid, const long ksp_dims[4], const complex float* src); extern void gridH(const struct grid_conf_s* conf, const complex float* traj, const long ksp_dims[4], complex float* dst, const long grid_dims[4], const complex float* grid); extern void grid2(const struct grid_conf_s* conf, unsigned int D, const long trj_dims[__VLA(D)], const complex float* traj, const long grid_dims[__VLA(D)], complex float* grid, const long ksp_dims[__VLA(D)], const complex float* src); extern void grid2H(const struct grid_conf_s* conf, unsigned int D, const long trj_dims[__VLA(D)], const complex float* traj, const long ksp_dims[__VLA(D)], complex float* dst, const long grid_dims[__VLA(D)], const complex float* grid); extern void grid_pointH(unsigned int ch, int N, const long dims[__VLA(N)], const float pos[__VLA(N)], complex float val[__VLA(ch)], const complex float* src, _Bool periodic, float width, int kb_size, const float kb_table[__VLA(kb_size + 1)]); extern void grid_point(unsigned int ch, int N, const long dims[__VLA(N)], const float pos[__VLA(N)], complex float* dst, const complex float val[__VLA(ch)], _Bool periodic, float width, int kb_size, const float kb_table[__VLA(kb_size + 1)]); extern double calc_beta(float os, float width); extern void rolloff_correction(float os, float width, float beta, const long dim[3], complex float* dst); #include "misc/cppwrap.h" bart-0.5.00/src/noncart/nudft.c000066400000000000000000000132161353046746100162570ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Author: * 2016 Martin Uecker */ #include #include "misc/misc.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/filter.h" #include "linops/linop.h" #include "nudft.h" static void get_coord(unsigned int N, unsigned long flags, float coord[N], long pos[N], const long tdims[N], const long tstrs[N], const complex float* traj) { assert(0 == pos[0]); unsigned int j = 0; for (unsigned int i = 0; i < N; i++) { coord[i] = 0.; if (MD_IS_SET(flags, i)) { pos[0] = j; coord[i] = -crealf(MD_ACCESS(N, tstrs, pos, traj)); j++; } } assert(tdims[0] == j); pos[0] = 0; } void nudft_forward2(unsigned int N, unsigned long flags, const long kdims[N], const long kstrs[N], complex float* ksp, const long idims[N], const long istrs[N], const complex float* img, const long tdims[N], const long tstrs[N], const complex float* traj) { assert(1 == kdims[0]); assert(md_check_compat(N, ~0, kdims, tdims)); long tmp_dims[N]; long tmp_strs[N]; md_select_dims(N, flags, tmp_dims, idims); md_calc_strides(N, tmp_strs, tmp_dims, CFL_SIZE); complex float* tmp = md_alloc(N, tmp_dims, CFL_SIZE); long kstrs2[N]; for (unsigned int i = 0; i < N; i++) kstrs2[i] = MD_IS_SET(flags, i) ? 0 : kstrs[i]; md_clear2(N, kdims, kstrs, ksp, CFL_SIZE); long pos[N]; for (unsigned int i = 0; i < N; i++) pos[i] = 0; do { float coord[N]; get_coord(N, flags, coord, pos, tdims, tstrs, traj); linear_phase(N, tmp_dims, coord, tmp); md_zfmac2(N, idims, kstrs2, &MD_ACCESS(N, kstrs, pos, ksp), istrs, img, tmp_strs, tmp); } while (md_next(N, tdims, ~MD_BIT(0), pos)); md_free(tmp); } /** * */ void nudft_adjoint2(unsigned int N, unsigned long flags, const long idims[N], const long istrs[N], complex float* img, const long kdims[N], const long kstrs[N], const complex float* ksp, const long tdims[N], const long tstrs[N], const complex float* traj) { assert(1 == kdims[0]); assert(md_check_compat(N, ~0, kdims, tdims)); long tmp_dims[N]; long tmp_strs[N]; md_select_dims(N, flags, tmp_dims, idims); md_calc_strides(N, tmp_strs, tmp_dims, CFL_SIZE); complex float* tmp = md_alloc(N, tmp_dims, CFL_SIZE); long kstrs2[N]; for (unsigned int i = 0; i < N; i++) kstrs2[i] = MD_IS_SET(flags, i) ? 0 : kstrs[i]; md_clear2(N, idims, istrs, img, CFL_SIZE); long pos[N]; for (unsigned int i = 0; i < N; i++) pos[i] = 0; do { float coord[N]; get_coord(N, flags, coord, pos, tdims, tstrs, traj); linear_phase(N, tmp_dims, coord, tmp); md_zfmacc2(N, idims, istrs, img, kstrs2, &MD_ACCESS(N, kstrs, pos, ksp), tmp_strs, tmp); } while (md_next(N, tdims, ~MD_BIT(0), pos)); md_free(tmp); } void nudft_forward(unsigned int N, unsigned long flags, const long odims[N], complex float* out, const long idims[N], const complex float* in, const long tdims[N], const complex float* traj) { long ostrs[N]; long istrs[N]; long tstrs[N]; md_calc_strides(N, ostrs, odims, CFL_SIZE); md_calc_strides(N, istrs, idims, CFL_SIZE); md_calc_strides(N, tstrs, tdims, CFL_SIZE); // FL_SIZE nudft_forward2(N, flags, odims, ostrs, out, idims, istrs, in, tdims, tstrs, traj); } struct nudft_s { linop_data_t base; unsigned int N; unsigned long flags; long* kdims; long* idims; long* tdims; long* kstrs; long* istrs; long* tstrs; const complex float* traj; }; static void nudft_apply(const linop_data_t* _data, complex float* out, const complex float* in) { const struct nudft_s* data = CONTAINER_OF(_data, const struct nudft_s, base); unsigned int N = data->N; nudft_forward2(N, data->flags, data->kdims, data->kstrs, out, data->idims, data->istrs, in, data->tdims, data->tstrs, data->traj); } static void nudft_adj(const linop_data_t* _data, complex float* out, const complex float* in) { const struct nudft_s* data = CONTAINER_OF(_data, const struct nudft_s, base); unsigned int N = data->N; nudft_adjoint2(N, data->flags, data->idims, data->istrs, out, data->kdims, data->kstrs, in, data->tdims, data->tstrs, data->traj); } static void nudft_delete(const linop_data_t* _data) { const struct nudft_s* data = CONTAINER_OF(_data, const struct nudft_s, base); xfree(data->kdims); xfree(data->idims); xfree(data->tdims); xfree(data->kstrs); xfree(data->istrs); xfree(data->tstrs); xfree(data); } const struct linop_s* nudft_create2(unsigned int N, unsigned long flags, const long odims[N], const long ostrs[N], const long idims[N], const long istrs[N], const long tdims[N], const complex float* traj) { PTR_ALLOC(struct nudft_s, data); data->N = N; data->flags = flags; data->traj = traj; data->kdims = *TYPE_ALLOC(long[N]); data->kstrs = *TYPE_ALLOC(long[N]); md_copy_dims(N, data->kdims, odims); md_copy_strides(N, data->kstrs, ostrs); data->idims = *TYPE_ALLOC(long[N]); data->istrs = *TYPE_ALLOC(long[N]); md_copy_dims(N, data->idims, idims); md_copy_strides(N, data->istrs, istrs); data->tdims = *TYPE_ALLOC(long[N]); data->tstrs = *TYPE_ALLOC(long[N]); md_copy_dims(N, data->tdims, tdims); md_calc_strides(N, data->tstrs, tdims, CFL_SIZE); return linop_create2(N, odims, ostrs, N, idims, istrs, &PTR_PASS(data)->base, nudft_apply, nudft_adj, NULL, NULL, nudft_delete); } const struct linop_s* nudft_create(unsigned int N, unsigned long flags, const long odims[N], const long idims[N], const long tdims[N], const complex float* traj) { return nudft_create2(N, flags, odims, MD_STRIDES(N, odims, CFL_SIZE), idims, MD_STRIDES(N, idims, CFL_SIZE), tdims, traj); } bart-0.5.00/src/noncart/nudft.h000066400000000000000000000026051353046746100162640ustar00rootroot00000000000000 #include extern void nudft_forward2(unsigned int N, unsigned long flags, const long odims[N], const long ostrs[N], complex float* out, const long idims[N], const long istrs[N], const complex float* in, const long tdims[N], const long tstrs[N], const complex float* traj); extern void nudft_forward(unsigned int N, unsigned long flags, const long odims[N], complex float* out, const long idims[N], const complex float* in, const long tdims[N], const complex float* traj); extern void nudft_adjoint2(unsigned int N, unsigned long flags, const long odims[N], const long ostrs[N], complex float* out, const long idims[N], const long istrs[N], const complex float* in, const long tdims[N], const long tstrs[N], const complex float* traj); extern void nudft_adjoint(unsigned int N, unsigned long flags, const long odims[N], complex float* out, const long idims[N], const complex float* in, const long tdims[N], const complex float* traj); struct linop_s; extern const struct linop_s* nudft_create2(unsigned int N, unsigned long flags, const long odims[N], const long ostrs[N], const long idims[N], const long istrs[N], const long tdims[N], const complex float* traj); extern const struct linop_s* nudft_create(unsigned int N, unsigned long flags, const long odims[N], const long idims[N], const long tdims[N], const complex float* traj); bart-0.5.00/src/noncart/nufft.c000066400000000000000000000635311353046746100162660ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2017 Frank Ong * 2014-2018 Martin Uecker * */ #include #include #include #include #include "misc/misc.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/filter.h" #include "num/fft.h" #include "num/shuffle.h" #include "num/ops.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "linops/linop.h" #include "linops/someops.h" #include "linops/fmac.h" #include "noncart/grid.h" #include "nufft.h" #define FFT_FLAGS (MD_BIT(0)|MD_BIT(1)|MD_BIT(2)) struct nufft_conf_s nufft_conf_defaults = { .toeplitz = true, .pcycle = false, .periodic = false, .lowmem = false, .flags = FFT_FLAGS, .cfft = 0u, }; #include "nufft_priv.h" DEF_TYPEID(nufft_data); static void nufft_free_data(const linop_data_t* data); static void nufft_apply(const linop_data_t* _data, complex float* dst, const complex float* src); static void nufft_apply_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src); static void nufft_apply_normal(const linop_data_t* _data, complex float* dst, const complex float* src); static void toeplitz_mult(const struct nufft_data* data, complex float* dst, const complex float* src); static complex float* compute_linphases(int N, long lph_dims[N + 1], unsigned long flags, const long img_dims[N + 1]) { int T = bitcount(flags); float shifts[1 << T][T]; int s = 0; for(int i = 0; i < (1 << T); i++) { bool skip = false; for(int j = 0; j < T; j++) { shifts[s][j] = 0.; if (MD_IS_SET(i, j)) { skip = skip || (1 == img_dims[j]); shifts[s][j] = -0.5; } } if (!skip) s++; } int ND = N + 1; md_select_dims(ND, flags, lph_dims, img_dims); lph_dims[N] = s; complex float* linphase = md_alloc(ND, lph_dims, CFL_SIZE); for(int i = 0; i < s; i++) { float shifts2[ND]; for (int j = 0; j < ND; j++) shifts2[j] = 0.; for (int j = 0, t = 0; j < N; j++) if (MD_IS_SET(flags, j)) shifts2[j] = shifts[i][t++]; linear_phase(ND, img_dims, shifts2, linphase + i * md_calc_size(ND, img_dims)); } return linphase; } static void compute_kern_basis(unsigned int N, unsigned int flags, const long pos[N], const long krn_dims[N], complex float* krn, const long bas_dims[N], const complex float* basis, const long wgh_dims[N], const complex float* weights) { // assert(1 == krn_dims[N - 1]); assert(1 == wgh_dims[N - 1]); assert(1 == bas_dims[N - 1]); long baT_dims[N]; md_copy_dims(N, baT_dims, bas_dims); baT_dims[N - 1] = bas_dims[5]; baT_dims[5] = 1; long wgT_dims[N]; md_copy_dims(N, wgT_dims, wgh_dims); wgT_dims[N - 1] = wgh_dims[5]; wgT_dims[5] = 1; long max_dims[N]; md_max_dims(N, ~0u, max_dims, baT_dims, wgT_dims); long max_strs[N]; md_calc_strides(N, max_strs, max_dims, CFL_SIZE); long bas_strs[N]; md_calc_strides(N, bas_strs, bas_dims, CFL_SIZE); long baT_strs[N]; md_copy_strides(N, baT_strs, bas_strs); baT_strs[N - 1] = bas_strs[5]; baT_strs[5] = 0; long wgh_strs[N]; md_calc_strides(N, wgh_strs, wgh_dims, CFL_SIZE); long wgT_strs[N]; md_copy_strides(N, wgT_strs, wgh_strs); wgT_strs[N - 1] = wgh_strs[5]; wgT_strs[5] = 0; debug_printf(DP_DEBUG1, "Allocating %ld\n", md_calc_size(N, max_dims)); complex float* tmp = md_alloc(N, max_dims, CFL_SIZE); md_copy2(N, max_dims, max_strs, tmp, baT_strs, basis, CFL_SIZE); md_zmul2(N, max_dims, max_strs, tmp, max_strs, tmp, wgT_strs, weights); md_zmulc2(N, max_dims, max_strs, tmp, max_strs, tmp, wgT_strs, weights); baT_dims[5] = baT_dims[6]; baT_dims[6] = 1; baT_strs[5] = baT_strs[6]; baT_strs[6] = 0; long krn_strs[N]; md_calc_strides(N, krn_strs, krn_dims, CFL_SIZE); long ma2_dims[N]; md_tenmul_dims(N, ma2_dims, krn_dims, max_dims, baT_dims); long ma3_dims[N]; md_select_dims(N, flags, ma3_dims, ma2_dims); long tmp_off = md_calc_offset(N, max_strs, pos); long bas_off = md_calc_offset(N, baT_strs, pos); md_zsmul(N, max_dims, tmp, tmp, (double)bas_dims[6]); // FIXME: Why? md_ztenmulc2(N, ma3_dims, krn_strs, krn, max_strs, (void*)tmp + tmp_off, baT_strs, (void*)basis + bas_off); md_free(tmp); } static void compute_kern(unsigned int N, unsigned int flags, const long pos[N], const long krn_dims[N], complex float* krn, const long bas_dims[N], const complex float* basis, const long wgh_dims[N], const complex float* weights) { if (NULL != basis) return compute_kern_basis(N, flags, pos, krn_dims, krn, bas_dims, basis, wgh_dims, weights); assert(~0u == flags); md_zfill(N, krn_dims, krn, 1.); if (NULL != weights) { long krn_strs[N]; md_calc_strides(N, krn_strs, krn_dims, CFL_SIZE); long wgh_strs[N]; md_calc_strides(N, wgh_strs, wgh_dims, CFL_SIZE); md_zmul2(N, krn_dims, krn_strs, krn, krn_strs, krn, wgh_strs, weights); md_zmulc2(N, krn_dims, krn_strs, krn, krn_strs, krn, wgh_strs, weights); } return; } complex float* compute_psf(unsigned int N, const long img_dims[N], const long trj_dims[N], const complex float* traj, const long bas_dims[N], const complex float* basis, const long wgh_dims[N], const complex float* weights, bool periodic, bool lowmem) { long img2_dims[N + 1]; md_copy_dims(N, img2_dims, img_dims); img2_dims[N] = 1; long trj2_dims[N + 1]; md_copy_dims(N, trj2_dims, trj_dims); trj2_dims[N] = 1; long bas2_dims[N + 1]; md_copy_dims(N, bas2_dims, bas_dims); bas2_dims[N] = 1; long wgh2_dims[N + 1]; md_copy_dims(N, wgh2_dims, wgh_dims); wgh2_dims[N] = 1; N++; long ksp2_dims[N]; md_copy_dims(N, ksp2_dims, img2_dims); md_select_dims(3, ~MD_BIT(0), ksp2_dims, trj2_dims); if (NULL != basis) { assert(1 == trj2_dims[6]); ksp2_dims[N - 1] = trj2_dims[5]; trj2_dims[N - 1] = trj2_dims[5]; trj2_dims[5] = 1; // FIXME copy? } struct nufft_conf_s conf = nufft_conf_defaults; conf.periodic = periodic; conf.toeplitz = false; // avoid infinite loop debug_printf(DP_DEBUG2, "nufft kernel dims: "); debug_print_dims(DP_DEBUG2, N, ksp2_dims); debug_printf(DP_DEBUG2, "nufft psf dims: "); debug_print_dims(DP_DEBUG2, N, img2_dims); debug_printf(DP_DEBUG2, "nufft traj dims: "); debug_print_dims(DP_DEBUG2, N, trj2_dims); complex float* psft = NULL; long pos[N]; for (unsigned int i = 0; i < N; i++) pos[i] = 0; long A = md_calc_size(N, ksp2_dims); long B = md_calc_size(N - 1, ksp2_dims) + md_calc_size(N - 1, img2_dims); long C = md_calc_size(N, img2_dims); if ((A <= B) || !lowmem) { debug_printf(DP_DEBUG1, "Allocating %ld (vs. %ld) + %ld\n", A, B, C); complex float* ones = md_alloc(N, ksp2_dims, CFL_SIZE); compute_kern(N, ~0u, pos, ksp2_dims, ones, bas2_dims, basis, wgh2_dims, weights); psft = md_alloc(N, img2_dims, CFL_SIZE); struct linop_s* op2 = nufft_create(N, ksp2_dims, img2_dims, trj2_dims, traj, NULL, conf); linop_adjoint_unchecked(op2, psft, ones); linop_free(op2); md_free(ones); } else { debug_printf(DP_DEBUG1, "Allocating %ld (vs. %ld) + %ld\n", B, A, C); psft = md_calloc(N, img2_dims, CFL_SIZE); long trj2_strs[N]; md_calc_strides(N, trj2_strs, trj2_dims, CFL_SIZE); complex float* ones = md_alloc(N - 1, ksp2_dims, CFL_SIZE); complex float* tmp = md_alloc(N - 1, img2_dims, CFL_SIZE); assert(!((1 != trj2_dims[N - 1]) && (NULL == basis))); for (long i = 0; i < trj2_dims[N - 1]; i++) { debug_printf(DP_DEBUG1, "KERN %03ld\n", i); unsigned int flags = ~0u; if (1 != trj2_dims[N - 1]) flags = ~(1u << (N - 1u)); pos[N - 1] = i; compute_kern(N, flags, pos, ksp2_dims, ones, bas2_dims, basis, wgh2_dims, weights); struct linop_s* op2 = nufft_create(N - 1, ksp2_dims, img2_dims, trj2_dims, (void*)traj + i * trj2_strs[N - 1], NULL, conf); linop_adjoint_unchecked(op2, tmp, ones); md_zadd(N - 1, img2_dims, psft, psft, tmp); linop_free(op2); } md_free(ones); md_free(tmp); } return psft; } static complex float* compute_psf2(int N, const long psf_dims[N + 1], unsigned long flags, const long trj_dims[N + 1], const complex float* traj, const long bas_dims[N + 1], const complex float* basis, const long wgh_dims[N + 1], const complex float* weights, bool periodic, bool lowmem) { int ND = N + 1; long img_dims[ND]; long img_strs[ND]; md_select_dims(ND, ~MD_BIT(N + 0), img_dims, psf_dims); md_calc_strides(ND, img_strs, img_dims, CFL_SIZE); // PSF 2x size long img2_dims[ND]; long img2_strs[ND]; md_copy_dims(ND, img2_dims, img_dims); for (int i = 0; i < N; i++) if (MD_IS_SET(flags, i)) img2_dims[i] = (1 == img_dims[i]) ? 1 : (2 * img_dims[i]); md_calc_strides(ND, img2_strs, img2_dims, CFL_SIZE); complex float* traj2 = md_alloc(ND, trj_dims, CFL_SIZE); md_zsmul(ND, trj_dims, traj2, traj, 2.); complex float* psft = compute_psf(ND, img2_dims, trj_dims, traj2, bas_dims, basis, wgh_dims, weights, periodic, lowmem); md_free(traj2); fftuc(ND, img2_dims, flags, psft, psft); float scale = 1.; for (int i = 0; i < N; i++) scale *= ((img2_dims[i] > 1) && (MD_IS_SET(flags, i))) ? 4. : 1.; md_zsmul(ND, img2_dims, psft, psft, scale); // reformat complex float* psf = md_alloc(ND, psf_dims, CFL_SIZE); long factors[N]; for (int i = 0; i < N; i++) factors[i] = ((img_dims[i] > 1) && (MD_IS_SET(flags, i))) ? 2 : 1; md_decompose(N + 0, factors, psf_dims, psf, img2_dims, psft, CFL_SIZE); md_free(psft); return psf; } struct linop_s* nufft_create2(unsigned int N, const long ksp_dims[N], const long cim_dims[N], const long traj_dims[N], const complex float* traj, const long wgh_dims[N], const complex float* weights, const long bas_dims[N], const complex float* basis, struct nufft_conf_s conf) { PTR_ALLOC(struct nufft_data, data); SET_TYPEID(nufft_data, data); data->N = N; data->traj = traj; data->conf = conf; data->flags = conf.flags; data->width = 3.; data->beta = calc_beta(2., data->width); debug_printf(DP_DEBUG1, "ksp : "); debug_print_dims(DP_DEBUG1, N, ksp_dims); debug_printf(DP_DEBUG1, "cim : "); debug_print_dims(DP_DEBUG1, N, cim_dims); debug_printf(DP_DEBUG1, "traj: "); debug_print_dims(DP_DEBUG1, N, traj_dims); if (NULL != weights) { debug_printf(DP_DEBUG1, "wgh : "); debug_print_dims(DP_DEBUG1, N, wgh_dims); } if (NULL != basis) { debug_printf(DP_DEBUG1, "bas : "); debug_print_dims(DP_DEBUG1, N, bas_dims); } // dim 0 must be transformed (we treat this special in the trajectory) assert(MD_IS_SET(data->flags, 0)); // assert(md_check_compat(N, ~data->flags, ksp_dims, cim_dims)); assert(md_check_bounds(N, ~data->flags, cim_dims, ksp_dims)); // extend internal dimensions by one for linear phases unsigned int ND = N + 1; data->ksp_dims = *TYPE_ALLOC(long[ND]); data->cim_dims = *TYPE_ALLOC(long[ND]); data->cml_dims = *TYPE_ALLOC(long[ND]); data->img_dims = *TYPE_ALLOC(long[ND]); data->trj_dims = *TYPE_ALLOC(long[ND]); data->lph_dims = *TYPE_ALLOC(long[ND]); data->psf_dims = *TYPE_ALLOC(long[ND]); data->wgh_dims = *TYPE_ALLOC(long[ND]); data->bas_dims = *TYPE_ALLOC(long[ND]); data->out_dims = *TYPE_ALLOC(long[ND]); data->ciT_dims = *TYPE_ALLOC(long[ND]); data->cmT_dims = *TYPE_ALLOC(long[ND]); data->ksp_strs = *TYPE_ALLOC(long[ND]); data->cim_strs = *TYPE_ALLOC(long[ND]); data->cml_strs = *TYPE_ALLOC(long[ND]); data->img_strs = *TYPE_ALLOC(long[ND]); data->trj_strs = *TYPE_ALLOC(long[ND]); data->lph_strs = *TYPE_ALLOC(long[ND]); data->psf_strs = *TYPE_ALLOC(long[ND]); data->wgh_strs = *TYPE_ALLOC(long[ND]); data->bas_strs = *TYPE_ALLOC(long[ND]); data->out_strs = *TYPE_ALLOC(long[ND]); md_copy_dims(N, data->cim_dims, cim_dims); data->cim_dims[N] = 1; md_copy_dims(N, data->ksp_dims, ksp_dims); data->ksp_dims[N] = 1; md_copy_dims(ND, data->ciT_dims, data->cim_dims); md_copy_dims(ND, data->out_dims, data->ksp_dims); md_select_dims(ND, data->flags, data->img_dims, data->cim_dims); assert(bitcount(data->flags) == traj_dims[0]); long chk_dims[N]; md_select_dims(N, ~data->flags, chk_dims, traj_dims); assert(md_check_compat(N, ~0ul, chk_dims, ksp_dims)); // assert(md_check_bounds(N, ~0ul, chk_dims, ksp_dims)); md_copy_dims(N, data->trj_dims, traj_dims); data->trj_dims[N] = 1; md_calc_strides(ND, data->cim_strs, data->cim_dims, CFL_SIZE); md_calc_strides(ND, data->img_strs, data->img_dims, CFL_SIZE); md_calc_strides(ND, data->trj_strs, data->trj_dims, CFL_SIZE); md_calc_strides(ND, data->ksp_strs, data->ksp_dims, CFL_SIZE); md_calc_strides(ND, data->out_strs, data->out_dims, CFL_SIZE); data->basis = NULL; if (NULL != basis) { // conf.toeplitz = false; assert(!md_check_dimensions(N, bas_dims, (1 << 5) | (1 << 6))); data->out_dims[5] = bas_dims[5]; // TE data->out_dims[6] = 1; // COEFF assert(data->ksp_dims[6] == bas_dims[6]); // recompute md_calc_strides(ND, data->out_strs, data->out_dims, CFL_SIZE); md_copy_dims(N, data->bas_dims, bas_dims); data->bas_dims[N] = 1; md_calc_strides(ND, data->bas_strs, data->bas_dims, CFL_SIZE); complex float* tmp = md_alloc(ND, data->bas_dims, CFL_SIZE); md_copy(ND, data->bas_dims, tmp, basis, CFL_SIZE); data->basis = tmp; } data->weights = NULL; if (NULL != weights) { md_copy_dims(N, data->wgh_dims, wgh_dims); data->wgh_dims[N] = 1; md_calc_strides(ND, data->wgh_strs, data->wgh_dims, CFL_SIZE); complex float* tmp = md_alloc(ND, data->wgh_dims, CFL_SIZE); md_copy(ND, data->wgh_dims, tmp, weights, CFL_SIZE); data->weights = tmp; } complex float* roll = md_alloc(ND, data->img_dims, CFL_SIZE); rolloff_correction(2., data->width, data->beta, data->img_dims, roll); data->roll = roll; complex float* linphase = compute_linphases(N, data->lph_dims, data->flags, data->img_dims); md_calc_strides(ND, data->lph_strs, data->lph_dims, CFL_SIZE); if (!conf.toeplitz) md_zmul2(ND, data->lph_dims, data->lph_strs, linphase, data->lph_strs, linphase, data->img_strs, data->roll); fftmod(ND, data->lph_dims, data->flags, linphase, linphase); fftscale(ND, data->lph_dims, data->flags, linphase, linphase); float scale = 1.; for (int i = 0; i < (int)N; i++) scale *= ((data->lph_dims[i] > 1) && (MD_IS_SET(data->flags, i))) ? 0.5 : 1.; md_zsmul(ND, data->lph_dims, linphase, linphase, scale); complex float* fftm = md_alloc(ND, data->img_dims, CFL_SIZE); md_zfill(ND, data->img_dims, fftm, 1.); fftmod(ND, data->img_dims, data->flags, fftm, fftm); data->fftmod = fftm; data->linphase = linphase; data->psf = NULL; #ifdef USE_CUDA data->linphase_gpu = NULL; data->psf_gpu = NULL; #endif if (conf.toeplitz) { debug_printf(DP_DEBUG1, "NUFFT: Toeplitz mode\n"); md_copy_dims(ND, data->psf_dims, data->lph_dims); for (int i = 0; i < (int)N; i++) if (!MD_IS_SET(data->flags, i)) data->psf_dims[i] = data->trj_dims[i]; if (NULL != basis) { debug_printf(DP_DEBUG3, "psf_dims: "); debug_print_dims(DP_DEBUG3, N, data->psf_dims); data->psf_dims[6] = data->bas_dims[6]; data->psf_dims[5] = data->bas_dims[6]; } md_calc_strides(ND, data->psf_strs, data->psf_dims, CFL_SIZE); data->psf = compute_psf2(N, data->psf_dims, data->flags, data->trj_dims, data->traj, data->bas_dims, data->basis, data->wgh_dims, data->weights, true /*conf.periodic*/, conf.lowmem); } md_copy_dims(ND, data->cml_dims, data->cim_dims); data->cml_dims[N + 0] = data->lph_dims[N + 0]; md_copy_dims(ND, data->cmT_dims, data->cml_dims); if (NULL != basis) { assert(1 == data->cml_dims[5]); data->cmT_dims[5] = data->cml_dims[6]; data->cmT_dims[6] = 1; assert(1 == data->cim_dims[5]); data->ciT_dims[5] = data->cim_dims[6]; data->ciT_dims[6] = 1; } md_calc_strides(ND, data->cml_strs, data->cml_dims, CFL_SIZE); data->cm2_dims = *TYPE_ALLOC(long[ND]); // ! md_copy_dims(ND, data->cm2_dims, data->cim_dims); for (int i = 0; i < (int)N; i++) if (MD_IS_SET(data->flags, i)) data->cm2_dims[i] = (1 == cim_dims[i]) ? 1 : (2 * cim_dims[i]); data->fft_op = linop_fft_create(ND, data->cml_dims, data->flags | data->conf.cfft); if (conf.pcycle || conf.lowmem) { debug_printf(DP_DEBUG1, "NUFFT: %s mode\n", conf.lowmem ? "low-mem" : "pcycle"); data->cycle = 0; data->cfft_op = linop_fft_create(N, data->cim_dims, data->flags | data->conf.cfft); } long out_dims[N]; md_copy_dims(N, out_dims, data->out_dims); return linop_create(N, out_dims, N, cim_dims, CAST_UP(PTR_PASS(data)), nufft_apply, nufft_apply_adjoint, nufft_apply_normal, NULL, nufft_free_data); } struct linop_s* nufft_create(unsigned int N, ///< Number of dimension const long ksp_dims[N], ///< kspace dimension const long cim_dims[N], ///< Coil images dimension const long traj_dims[N], ///< Trajectory dimension const complex float* traj, ///< Trajectory const complex float* weights, ///< Weights, ex, soft-gating or density compensation struct nufft_conf_s conf) ///< NUFFT configuration options { long wgh_dims[N]; md_select_dims(N, ~MD_BIT(0), wgh_dims, traj_dims); return nufft_create2(N, ksp_dims, cim_dims, traj_dims, traj, wgh_dims, weights, NULL, NULL, conf); } static void nufft_free_data(const linop_data_t* _data) { auto data = CAST_DOWN(nufft_data, _data); xfree(data->ksp_dims); xfree(data->cim_dims); xfree(data->cml_dims); xfree(data->img_dims); xfree(data->trj_dims); xfree(data->lph_dims); xfree(data->psf_dims); xfree(data->wgh_dims); xfree(data->bas_dims); xfree(data->out_dims); xfree(data->ciT_dims); xfree(data->cmT_dims); xfree(data->ksp_strs); xfree(data->cim_strs); xfree(data->cml_strs); xfree(data->img_strs); xfree(data->trj_strs); xfree(data->lph_strs); xfree(data->psf_strs); xfree(data->wgh_strs); xfree(data->bas_strs); xfree(data->out_strs); xfree(data->cm2_dims); md_free(data->linphase); md_free(data->psf); md_free(data->fftmod); md_free(data->weights); md_free(data->roll); md_free(data->basis); #ifdef USE_CUDA md_free(data->linphase_gpu); md_free(data->psf_gpu); #endif linop_free(data->fft_op); if (data->conf.pcycle || data->conf.lowmem) linop_free(data->cfft_op); xfree(data); } // Forward: from image to kspace static void nufft_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nufft_data, _data); #ifdef USE_CUDA assert(!cuda_ondevice(src)); #endif assert(!data->conf.toeplitz); // if toeplitz linphase has no roll, so would need to be added int ND = data->N + 1; complex float* grid = md_alloc(ND, data->cml_dims, CFL_SIZE); md_zmul2(ND, data->cml_dims, data->cml_strs, grid, data->cim_strs, src, data->lph_strs, data->linphase); linop_forward(data->fft_op, ND, data->cml_dims, grid, ND, data->cml_dims, grid); md_zmul2(ND, data->cml_dims, data->cml_strs, grid, data->cml_strs, grid, data->img_strs, data->fftmod); complex float* gridX = md_alloc(data->N, data->cm2_dims, CFL_SIZE); long factors[data->N]; for (int i = 0; i < (int)data->N; i++) factors[i] = ((data->img_dims[i] > 1) && MD_IS_SET(data->flags, i)) ? 2 : 1; md_recompose(data->N, factors, data->cm2_dims, gridX, data->cml_dims, grid, CFL_SIZE); md_free(grid); struct grid_conf_s conf = { .width = data->width, .os = 2., .periodic = data->conf.periodic, .beta = data->beta, }; complex float* tmp = dst; if (NULL != data->basis) tmp = md_alloc(ND, data->ksp_dims, CFL_SIZE); md_clear(ND, data->ksp_dims, tmp, CFL_SIZE); grid2H(&conf, ND, data->trj_dims, data->traj, data->ksp_dims, tmp, data->cm2_dims, gridX); md_free(gridX); if (NULL != data->basis) { md_ztenmul(data->N, data->out_dims, dst, data->ksp_dims, tmp, data->bas_dims, data->basis); md_free(tmp); } if (NULL != data->weights) md_zmul2(data->N, data->out_dims, data->out_strs, dst, data->out_strs, dst, data->wgh_strs, data->weights); } // Adjoint: from kspace to image static void nufft_apply_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nufft_data, _data); #ifdef USE_CUDA assert(!cuda_ondevice(src)); #endif int ND = data->N + 1; complex float* wdat = NULL; if (NULL != data->weights) { wdat = md_alloc(data->N, data->out_dims, CFL_SIZE); md_zmulc2(data->N, data->out_dims, data->out_strs, wdat, data->out_strs, src, data->wgh_strs, data->weights); src = wdat; } complex float* bdat = NULL; if (NULL != data->basis) { bdat = md_alloc(data->N, data->ksp_dims, CFL_SIZE); md_ztenmulc(data->N, data->ksp_dims, bdat, data->out_dims, src, data->bas_dims, data->basis); src = bdat; } struct grid_conf_s conf = { .width = data->width, .os = 2., .periodic = data->conf.periodic, .beta = data->beta, }; complex float* gridX = md_calloc(data->N, data->cm2_dims, CFL_SIZE); grid2(&conf, ND, data->trj_dims, data->traj, data->cm2_dims, gridX, data->ksp_dims, src); md_free(bdat); md_free(wdat); long factors[data->N]; for (int i = 0; i < (int)data->N; i++) factors[i] = ((data->img_dims[i] > 1) && MD_IS_SET(data->flags, i)) ? 2 : 1; complex float* grid = md_alloc(ND, data->cml_dims, CFL_SIZE); md_decompose(data->N, factors, data->cml_dims, grid, data->cm2_dims, gridX, CFL_SIZE); md_free(gridX); md_zmulc2(ND, data->cml_dims, data->cml_strs, grid, data->cml_strs, grid, data->img_strs, data->fftmod); linop_adjoint(data->fft_op, ND, data->cml_dims, grid, ND, data->cml_dims, grid); md_clear(ND, data->cim_dims, dst, CFL_SIZE); md_zfmacc2(ND, data->cml_dims, data->cim_strs, dst, data->cml_strs, grid, data->lph_strs, data->linphase); md_free(grid); if (data->conf.toeplitz) md_zmul2(ND, data->cim_dims, data->cim_strs, dst, data->cim_strs, dst, data->img_strs, data->roll); } #ifdef USE_CUDA static void gpu_alloc(const struct nufft_data* data) { unsigned int ND = data->N + 1; if (NULL == data->linphase_gpu) ((struct nufft_data*)data)->linphase_gpu = md_gpu_move(ND, data->lph_dims, data->linphase, CFL_SIZE); if (NULL == data->psf_gpu) ((struct nufft_data*)data)->psf_gpu = md_gpu_move(ND, data->psf_dims, data->psf, CFL_SIZE); } #endif static void toeplitz_mult(const struct nufft_data* data, complex float* dst, const complex float* src) { unsigned int ND = data->N + 1; const complex float* linphase = data->linphase; const complex float* psf = data->psf; #ifdef USE_CUDA if (cuda_ondevice(src)) { gpu_alloc(data); linphase = data->linphase_gpu; psf = data->psf_gpu; } #endif complex float* grid = md_alloc_sameplace(ND, data->cml_dims, CFL_SIZE, dst); md_zmul2(ND, data->cml_dims, data->cml_strs, grid, data->cim_strs, src, data->lph_strs, linphase); linop_forward(data->fft_op, ND, data->cml_dims, grid, ND, data->cml_dims, grid); complex float* gridT = md_alloc_sameplace(ND, data->cmT_dims, CFL_SIZE, dst); md_ztenmul(ND, data->cmT_dims, gridT, data->cml_dims, grid, data->psf_dims, psf); md_free(grid); linop_adjoint(data->fft_op, ND, data->cml_dims, gridT, ND, data->cml_dims, gridT); md_clear(ND, data->cim_dims, dst, CFL_SIZE); md_zfmacc2(ND, data->cml_dims, data->cim_strs, dst, data->cml_strs, gridT, data->lph_strs, linphase); md_free(gridT); } static void toeplitz_mult_lowmem(const struct nufft_data* data, int i, complex float* dst, const complex float* src) { const complex float* linphase = data->linphase; const complex float* psf = data->psf; #ifdef USE_CUDA if (cuda_ondevice(src)) { gpu_alloc(data); linphase = data->linphase_gpu; psf = data->psf_gpu; } #endif const complex float* clinphase = linphase + i * md_calc_size(data->N, data->lph_dims); const complex float* cpsf = psf + i * md_calc_size(data->N, data->psf_dims); complex float* grid = md_alloc_sameplace(data->N, data->cim_dims, CFL_SIZE, dst); md_zmul2(data->N, data->cim_dims, data->cim_strs, grid, data->cim_strs, src, data->img_strs, clinphase); linop_forward(data->cfft_op, data->N, data->cim_dims, grid, data->N, data->cim_dims, grid); complex float* gridT = md_alloc_sameplace(data->N, data->ciT_dims, CFL_SIZE, dst); md_ztenmul(data->N, data->ciT_dims, gridT, data->cim_dims, grid, data->psf_dims, cpsf); md_free(grid); linop_adjoint(data->cfft_op, data->N, data->cim_dims, gridT, data->N, data->cim_dims, gridT); md_zfmacc2(data->N, data->cim_dims, data->cim_strs, dst, data->cim_strs, gridT, data->img_strs, clinphase); md_free(gridT); } static void toeplitz_mult_pcycle(const struct nufft_data* data, complex float* dst, const complex float* src) { unsigned int ncycles = data->lph_dims[data->N]; ((struct nufft_data*) data)->cycle = (data->cycle + 1) % ncycles; // FIXME: assert(dst != src); md_clear(data->N, data->cim_dims, dst, CFL_SIZE); toeplitz_mult_lowmem(data, data->cycle, dst, src); } static void nufft_apply_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(nufft_data, _data); if (data->conf.toeplitz) { if (data->conf.pcycle) { toeplitz_mult_pcycle(data, dst, src); } else if (data->conf.lowmem) { int ncycles = data->lph_dims[data->N]; assert(dst != src); md_clear(data->N, data->cim_dims, dst, CFL_SIZE); for (int i = 0; i < ncycles; i++) toeplitz_mult_lowmem(data, i, dst, src); } else { toeplitz_mult(data, dst, src); } } else { complex float* tmp_ksp = md_alloc(data->N + 1, data->out_dims, CFL_SIZE); nufft_apply(_data, tmp_ksp, src); nufft_apply_adjoint(_data, dst, tmp_ksp); md_free(tmp_ksp); } } /** * Estimate image dimensions from trajectory */ void estimate_im_dims(int N, unsigned long flags, long dims[N], const long tdims[N], const complex float* traj) { int T = tdims[0]; assert(T == (int)bitcount(flags)); float max_dims[T]; for (int i = 0; i < T; i++) max_dims[i] = 0.; for (long i = 0; i < md_calc_size(N - 1, tdims + 1); i++) for(int j = 0; j < tdims[0]; j++) max_dims[j] = MAX(cabsf(traj[j + tdims[0] * i]), max_dims[j]); for (int j = 0, t = 0; j < N; j++) { dims[j] = 1; if (MD_IS_SET(flags, j)) { dims[t] = (0. == max_dims[t]) ? 1 : (2 * (long)((2. * max_dims[t] + 1.5) / 2.)); t++; } } } bart-0.5.00/src/noncart/nufft.h000066400000000000000000000036741353046746100162750ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" struct operator_s; struct linop_s; struct nufft_conf_s { _Bool toeplitz; ///< Toeplitz embedding boolean for A^T A _Bool pcycle; /// < Phase cycling _Bool periodic; _Bool lowmem; unsigned long flags; unsigned long cfft; }; extern struct nufft_conf_s nufft_conf_defaults; extern struct linop_s* nufft_create(unsigned int N, ///< Number of dimensions const long ksp_dims[__VLA(N)], ///< Kspace dimension const long coilim_dims[__VLA(N)], ///< Coil image dimension const long traj_dims[__VLA(N)], ///< Trajectory dimension const _Complex float* traj, ///< Trajectory const _Complex float* weights, ///< Weights, ex, density-compensation struct nufft_conf_s conf); ///< NUFFT configuration extern struct linop_s* nufft_create2(unsigned int N, const long ksp_dims[N], const long cim_dims[N], const long traj_dims[N], const complex float* traj, const long wgh_dims[N], const complex float* weights, const long bas_dims[N], const complex float* basis, struct nufft_conf_s conf); extern _Complex float* compute_psf(unsigned int N, const long img2_dims[__VLA(N)], const long trj_dims[__VLA(N)], const complex float* traj, const long bas_dims[__VLA(N)], const complex float* basis, const long wgh_dims[__VLA(N)], const complex float* weights, _Bool periodic, _Bool lowmem); extern void estimate_im_dims(int N, unsigned long flags, long dims[__VLA(N)], const long tdims[__VLA(N)], const complex float* traj); extern const struct operator_s* nufft_precond_create(const struct linop_s* nufft_op); #include "misc/cppwrap.h" bart-0.5.00/src/noncart/nufft_priv.h000066400000000000000000000033321353046746100173240ustar00rootroot00000000000000 /** * * NUFFT internal data structure * */ struct nufft_data { INTERFACE(linop_data_t); struct nufft_conf_s conf; ///< NUFFT configuration structure unsigned int N; ///< Number of dimension unsigned long flags; const complex float* linphase; ///< Linear phase for pruned FFT const complex float* traj; ///< Trajectory const complex float* roll; ///< Roll-off factor const complex float* psf; ///< Point-spread function (2x size) const complex float* fftmod; ///< FFT modulation for centering const complex float* weights; ///< Weights, ex, density compensation const complex float* basis; #ifdef USE_CUDA const complex float* linphase_gpu; const complex float* psf_gpu; complex float* grid_gpu; #endif complex float* grid; ///< Oversampling grid float width; ///< Interpolation kernel width double beta; ///< Kaiser-Bessel beta parameter const struct linop_s* fft_op; ///< FFT operator long* ksp_dims; ///< Kspace dimension long* cim_dims; ///< Coil image dimension long* cml_dims; ///< Coil + linear phase dimension long* img_dims; ///< Image dimension long* trj_dims; ///< Trajectory dimension long* lph_dims; ///< Linear phase dimension long* psf_dims; ///< Point spread function dimension long* wgh_dims; ///< Weights dimension long* bas_dims; long* out_dims; long* ciT_dims; ///< Coil image dimension long* cmT_dims; ///< Coil + linear phase dimension //! long* cm2_dims; ///< 2x oversampled coil image dimension long* ksp_strs; long* cim_strs; long* cml_strs; long* img_strs; long* trj_strs; long* lph_strs; long* psf_strs; long* wgh_strs; long* bas_strs; long* out_strs; const struct linop_s* cfft_op; ///< Pcycle FFT operator unsigned int cycle; }; bart-0.5.00/src/noncart/precond.c000066400000000000000000000101201353046746100165600ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2017 Frank Ong * 2014-2017 Martin Uecker * * Strang G. A proposal for Toeplitz matrix calculations. * Journal Studies in Applied Math. 1986; 74:171-17. (FIXME) * */ #include #include #include #include "misc/misc.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/ops.h" #include "linops/linop.h" #include "linops/someops.h" #include "noncart/nufft.h" #include "noncart/nufft_priv.h" #include "precond.h" #define FFT_FLAGS (MD_BIT(0)|MD_BIT(1)|MD_BIT(2)) /** * Compute Strang's circulant preconditioner * * Strang's reconditioner is simply the cropped psf in the image domain * */ static complex float* compute_precond(unsigned int N, const long* pre_dims, const long* pre_strs, const long* psf_dims, const long* psf_strs, const complex float* psf, const complex float* linphase) { int ND = N + 1; unsigned long flags = FFT_FLAGS; complex float* pre = md_alloc(ND, pre_dims, CFL_SIZE); complex float* psft = md_alloc(ND, psf_dims, CFL_SIZE); // Transform psf to image domain ifftuc(ND, psf_dims, flags, psft, psf); // Compensate for linear phase to get cropped psf md_clear(ND, pre_dims, pre, CFL_SIZE); md_zfmacc2(ND, psf_dims, pre_strs, pre, psf_strs, psft, psf_strs, linphase); md_free(psft); // Transform to Fourier domain fftuc(N, pre_dims, flags, pre, pre); md_zabs(N, pre_dims, pre, pre); md_zsadd(N, pre_dims, pre, pre, 1e-3); return pre; } /** * NUFFT precondition internal data structure */ struct nufft_precond_data { INTERFACE(operator_data_t); unsigned int N; const complex float* pre; ///< Preconditioner long* cim_dims; ///< Coil image dimension long* pre_dims; ///< Preconditioner dimension long* cim_strs; long* pre_strs; const struct linop_s* fft_op; ///< FFT linear operator }; static DEF_TYPEID(nufft_precond_data); static void nufft_precond_apply(const operator_data_t* _data, unsigned int M, void* args[M]) { assert(2 == M); const auto data = CAST_DOWN(nufft_precond_data, _data); complex float* dst = args[0]; const complex float* src = args[1]; linop_forward(data->fft_op, data->N, data->cim_dims, dst, data->N, data->cim_dims, src); md_zdiv2(data->N, data->cim_dims, data->cim_strs, dst, data->cim_strs, dst, data->pre_strs, data->pre); linop_adjoint(data->fft_op, data->N, data->cim_dims, dst, data->N, data->cim_dims, dst); } static void nufft_precond_del(const operator_data_t* _data) { const auto data = CAST_DOWN(nufft_precond_data, _data); xfree(data->cim_dims); xfree(data->pre_dims); xfree(data->cim_strs); xfree(data->pre_strs); md_free(data->pre); xfree(data); } const struct operator_s* nufft_precond_create(const struct linop_s* nufft_op) { const auto data = CAST_DOWN(nufft_data, linop_get_data(nufft_op)); PTR_ALLOC(struct nufft_precond_data, pdata); SET_TYPEID(nufft_precond_data, pdata); assert(data->conf.toeplitz); int N = data->N; int ND = N + 1; pdata->N = N; pdata->cim_dims = *TYPE_ALLOC(long[ND]); pdata->pre_dims = *TYPE_ALLOC(long[ND]); pdata->cim_strs = *TYPE_ALLOC(long[ND]); pdata->pre_strs = *TYPE_ALLOC(long[ND]); md_copy_dims(ND, pdata->cim_dims, data->cim_dims); md_select_dims(ND, data->flags, pdata->pre_dims, pdata->cim_dims); md_calc_strides(ND, pdata->cim_strs, pdata->cim_dims, CFL_SIZE); md_calc_strides(ND, pdata->pre_strs, pdata->pre_dims, CFL_SIZE); pdata->pre = compute_precond(pdata->N, pdata->pre_dims, pdata->pre_strs, data->psf_dims, data->psf_strs, data->psf, data->linphase); pdata->fft_op = linop_fft_create(pdata->N, pdata->cim_dims, data->flags); const long* cim_dims = pdata->cim_dims; // need to dereference pdata before PTR_PASS return operator_create(N, cim_dims, N, cim_dims, CAST_UP(PTR_PASS(pdata)), nufft_precond_apply, nufft_precond_del); } bart-0.5.00/src/noncart/precond.h000066400000000000000000000005711353046746100165760ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" struct operator_s; struct linop_s; extern const struct operator_s* nufft_precond_create(const struct linop_s* nufft_op); #include "misc/cppwrap.h" bart-0.5.00/src/noncart/traj.c000066400000000000000000000074161353046746100161040ustar00rootroot00000000000000/* Copyright 2014-2015 The Regents of the University of California. * Copyright 2015-2019 Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2014-2019 Martin Uecker * 2018-2019 Sebastian Rosenzweig */ #include #include #include "misc/mri.h" #include "traj.h" const struct traj_conf traj_defaults = { .radial = false, .golden = false, .aligned = false, .full_circle = false, .half_circle_gold = false, .golden_partition = false, .d3d = false, .transverse = false, .asym_traj = false, .accel = 1, .tiny_gold = 0, }; const struct traj_conf rmfreq_defaults = { .radial = true, .golden = false, .aligned = false, .full_circle = false, .half_circle_gold = false, .golden_partition = false, .d3d = false, .transverse = false, .asym_traj = false, .accel = 1, .tiny_gold = 0, }; void euler(float dir[3], float phi, float psi) { dir[0] = cosf(phi) * cosf(psi); dir[1] = sinf(phi) * cosf(psi); dir[2] = sinf(psi); } /* We allow an arbitrary quadratic form to account for * non-physical coordinate systems. * Moussavi et al., MRM 71:308-312 (2014) */ void gradient_delay(float d[3], float coeff[2][3], float phi, float psi) { float dir[3]; euler(dir, phi, psi); float mat[3][3] = { { coeff[0][0], coeff[0][2], coeff[1][1] }, { coeff[0][2], coeff[0][1], coeff[1][2] }, { coeff[1][1], coeff[1][2], coeff[1][0] }, }; for (unsigned int i = 0; i < 3; i++) { d[i] = 0.; for (unsigned int j = 0; j < 3; j++) d[i] += mat[i][j] * dir[j]; } } void calc_base_angles(double base_angle[DIMS], int Y, int mb, int turns, struct traj_conf conf) { /* Golden-ratio sampling * Winkelmann S, Schaeffter T, Koehler T, Eggers H, Doessel O. * An optimal radial profile order based on the Golden Ratio * for time-resolved MRI. IEEE TMI 26:68--76 (2007) */ double golden_ratio = (sqrtf(5.) + 1.) / 2; /* Tiny golden angle * Wundrak S, Paul J, Ulrici J, Hell E, Geibel MA, Bernhardt P, Rottbauer W, Rasche V. * Golden ratio sparse MRI using tiny golden angles. * Magn Reson Med 75:2372-2378 (2016) */ double golden_angle = M_PI / (golden_ratio + conf.tiny_gold - 1.); double angle_atom = M_PI / Y; // Angle between spokes of one slice/partition double angle_s = angle_atom * (conf.full_circle ? 2 : 1); // Angle between slices/partitions double angle_m = angle_atom / mb; // linear-turned partitions if (conf.aligned) angle_m = 0; // Angle between turns double angle_t = 0.; if (turns > 1) angle_t = angle_atom / (turns * mb) * (conf.full_circle ? 2 : 1); // Golden Angle if (conf.golden) { if (conf.aligned) { angle_s = golden_angle; angle_m = 0; angle_t = golden_angle * Y; } else { angle_s = golden_angle; angle_m = golden_angle * Y; angle_t = golden_angle * Y * mb; } } base_angle[PHS2_DIM] = angle_s; base_angle[SLICE_DIM] = angle_m; base_angle[TIME_DIM] = angle_t; } // z-Undersampling bool zpartition_skip(long partitions, long z_usamp[2], long partition, long frame) { long z_reflines = z_usamp[0]; long z_acc = z_usamp[1]; if (1 == z_acc) // No undersampling. Do not skip partition return false; // Auto-Calibration region long DC_idx = partitions / 2; long AC_lowidx = DC_idx - floor(z_reflines / 2.); long AC_highidx = DC_idx + ceil(z_reflines / 2.) - 1; if ((partition >= AC_lowidx) && (partition <= AC_highidx)) // Auto-calibration line. Do not skip partition. return false; // Check if this non-Auto-calibration line should be sampled. long part = (partition < AC_lowidx) ? partition : (partition - AC_highidx - 1); if (0 == ((part - (frame % z_acc)) % z_acc)) return false; return true; } bart-0.5.00/src/noncart/traj.h000066400000000000000000000020361353046746100161020ustar00rootroot00000000000000/* Copyright 2014-2015 The Regents of the University of California. * Copyright 2015-2019 Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2018 Martin Uecker * 2018 Sebastian Rosenzweig */ struct traj_conf { _Bool radial; _Bool golden; _Bool aligned; _Bool full_circle; _Bool half_circle_gold; _Bool golden_partition; _Bool d3d; _Bool transverse; _Bool asym_traj; int accel; int tiny_gold; }; extern const struct traj_conf traj_defaults; extern const struct traj_conf rmfreq_defaults; #ifndef DIMS #define DIMS 16 #endif extern void euler(float dir[3], float phi, float psi); extern void gradient_delay(float d[3], float coeff[2][3], float phi, float psi); extern void calc_base_angles(double base_angle[DIMS], int Y, int mb, int turns, struct traj_conf conf); extern bool zpartition_skip(long partitions, long z_usamp[2], long partition, long frame); bart-0.5.00/src/normalize.c000066400000000000000000000022051353046746100154670ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2014 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/utils.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "flags "; static const char help_str[] = "Normalize along selected dimensions.\n"; int main_normalize(int argc, char* argv[]) { bool l1 = false; l1 = mini_cmdline_bool(&argc, argv, 'b', 3, usage_str, help_str); num_init(); int N = DIMS; long dims[N]; complex float* data = load_cfl(argv[2], N, dims); int flags = atoi(argv[1]); assert(flags >= 0); complex float* out = create_cfl(argv[3], N, dims); md_copy(N, dims, out, data, CFL_SIZE); (l1 ? normalizel1 : normalize)(N, flags, dims, out); unmap_cfl(N, dims, out); return 0; } bart-0.5.00/src/nrmse.c000077500000000000000000000036331353046746100146240ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Dara Bahri * 2014 Frank Ong * 2014 Jonathan Tamir * 2015-2016 Martin Uecker */ #include #include #include #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Output normalized root mean square error (NRMSE),\n" "i.e. norm(input - ref) / norm(ref)"; int main_nrmse(int argc, char* argv[]) { float test = -1.; bool auto_scale = false; const struct opt_s opts[] = { OPT_FLOAT('t', &test, "eps", "compare to eps"), OPT_SET('s', &auto_scale, "automatic (complex) scaling"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long ref_dims[DIMS]; long in_dims[DIMS]; complex float* ref = load_cfl(argv[1], DIMS, ref_dims); complex float* in = load_cfl(argv[2], DIMS, in_dims); assert(md_check_compat(DIMS, 0u, in_dims, ref_dims)); if (auto_scale) { complex float sc = md_zscalar(DIMS, ref_dims, in, ref); float n = md_znorm(DIMS, ref_dims, ref); if (0. == n) error("Reference has zero norm"); sc /= n * n; debug_printf(DP_INFO, "Scaled by: %f%+fi\n", crealf(sc), cimagf(sc)); md_zsmul(DIMS, ref_dims, ref, ref, sc); } float err = md_znrmse(DIMS, ref_dims, ref, in); bart_printf("%f\n", err); unmap_cfl(DIMS, ref_dims, ref); unmap_cfl(DIMS, in_dims, in); return ((test == -1.) || (err <= test)) ? 0 : 1; } bart-0.5.00/src/nufft.c000066400000000000000000000106561353046746100146220ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2015-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong * 2014-2017 Martin Uecker */ #include #include #include #include "misc/mmio.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "misc/opts.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "num/ops.h" #include "linops/linop.h" #include "iter/iter.h" #include "iter/lsqr.h" #include "noncart/nufft.h" #include "noncart/nudft.h" #include "noncart/precond.h" static const char usage_str[] = " "; static const char help_str[] = "Perform non-uniform Fast Fourier Transform."; int main_nufft(int argc, char* argv[]) { bool adjoint = false; bool inverse = false; bool precond = false; bool dft = false; bool gpu = false; struct nufft_conf_s conf = nufft_conf_defaults; struct iter_conjgrad_conf cgconf = iter_conjgrad_defaults; long coilim_vec[3] = { 0 }; float lambda = 0.; const struct opt_s opts[] = { OPT_SET('a', &adjoint, "adjoint"), OPT_SET('i', &inverse, "inverse"), OPT_VEC3('d', &coilim_vec, "x:y:z", "dimensions"), OPT_VEC3('D', &coilim_vec, "", "()"), OPT_SET('t', &conf.toeplitz, "Toeplitz embedding for inverse NUFFT"), OPT_CLEAR('r', &conf.toeplitz, "turn-off Toeplitz embedding for inverse NUFFT"), OPT_SET('c', &precond, "Preconditioning for inverse NUFFT"), OPT_FLOAT('l', &lambda, "lambda", "l2 regularization"), OPT_UINT('m', &cgconf.maxiter, "", "()"), OPT_SET('P', &conf.periodic, "periodic k-space"), OPT_SET('s', &dft, "DFT"), OPT_SET('g', &gpu, "GPU (only inverse)"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); // avoid computing PSF if not necessary if (!inverse) conf.toeplitz = false; long coilim_dims[DIMS] = { 0 }; md_copy_dims(3, coilim_dims, coilim_vec); // Read trajectory long traj_dims[DIMS]; complex float* traj = load_cfl(argv[1], DIMS, traj_dims); assert(3 == traj_dims[0]); (gpu ? num_init_gpu : num_init)(); if (inverse || adjoint) { long ksp_dims[DIMS]; const complex float* ksp = load_cfl(argv[2], DIMS, ksp_dims); assert(1 == ksp_dims[0]); assert(md_check_compat(DIMS, ~(PHS1_FLAG|PHS2_FLAG), ksp_dims, traj_dims)); if (0 == md_calc_size(3, coilim_dims)) { estimate_im_dims(DIMS, FFT_FLAGS, coilim_dims, traj_dims, traj); debug_printf(DP_INFO, "Est. image size: %ld %ld %ld\n", coilim_dims[0], coilim_dims[1], coilim_dims[2]); } md_copy_dims(DIMS - 3, coilim_dims + 3, ksp_dims + 3); complex float* img = create_cfl(argv[3], DIMS, coilim_dims); md_clear(DIMS, coilim_dims, img, CFL_SIZE); const struct linop_s* nufft_op; if (!dft) nufft_op = nufft_create(DIMS, ksp_dims, coilim_dims, traj_dims, traj, NULL, conf); else nufft_op = nudft_create(DIMS, FFT_FLAGS, ksp_dims, coilim_dims, traj_dims, traj); if (inverse) { const struct operator_s* precond_op = NULL; if (conf.toeplitz && precond) precond_op = nufft_precond_create(nufft_op); lsqr(DIMS, &(struct lsqr_conf){ lambda, gpu }, iter_conjgrad, CAST_UP(&cgconf), nufft_op, NULL, coilim_dims, img, ksp_dims, ksp, precond_op); if (conf.toeplitz && precond) operator_free(precond_op); } else { linop_adjoint(nufft_op, DIMS, coilim_dims, img, DIMS, ksp_dims, ksp); } linop_free(nufft_op); unmap_cfl(DIMS, ksp_dims, ksp); unmap_cfl(DIMS, coilim_dims, img); } else { // Read image data const complex float* img = load_cfl(argv[2], DIMS, coilim_dims); // Initialize kspace data long ksp_dims[DIMS]; md_select_dims(DIMS, PHS1_FLAG|PHS2_FLAG, ksp_dims, traj_dims); md_copy_dims(DIMS - 3, ksp_dims + 3, coilim_dims + 3); complex float* ksp = create_cfl(argv[3], DIMS, ksp_dims); const struct linop_s* nufft_op; if (!dft) nufft_op = nufft_create(DIMS, ksp_dims, coilim_dims, traj_dims, traj, NULL, conf); else nufft_op = nudft_create(DIMS, FFT_FLAGS, ksp_dims, coilim_dims, traj_dims, traj); // nufft linop_forward(nufft_op, DIMS, ksp_dims, ksp, DIMS, coilim_dims, img); linop_free(nufft_op); unmap_cfl(DIMS, coilim_dims, img); unmap_cfl(DIMS, ksp_dims, ksp); } unmap_cfl(DIMS, traj_dims, traj); debug_printf(DP_INFO, "Done.\n"); return 0; } bart-0.5.00/src/num/000077500000000000000000000000001353046746100141235ustar00rootroot00000000000000bart-0.5.00/src/num/blas.c000066400000000000000000000037221353046746100152140ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jonathan Tamir * 2016 Martin Uecker */ #include #include #include "misc/misc.h" #ifdef USE_MACPORTS #include #else #include #endif #ifdef USE_CUDA #include "num/gpuops.h" #include #endif #include "blas.h" void blas_cgemm(char transa, char transb, long M, long N, long K, const complex float alpha, long lda, const complex float A[K][lda], long ldb, const complex float B[N][ldb], const complex float beta, long ldc, complex float C[N][ldc]) { #ifdef USE_CUDA #define CUCOMPLEX(x) (((union { cuComplex cu; complex float std; }){ .std = (x) }).cu) if (cuda_ondevice(A)) { cublasCgemm(transa, transb, M, N, K, CUCOMPLEX(alpha), (const cuComplex*)A, lda, (const cuComplex*)B, ldb, CUCOMPLEX(beta), (cuComplex*)C, ldc); } else #endif cblas_cgemm(CblasColMajor, transa, transb, M, N, K, (void*)&alpha, (void*)A, lda, (void*)B, ldb, (void*)&beta, (void*)C, ldc); } void (blas_matrix_multiply)(long M, long N, long K, complex float C[N][M], const complex float A[K][M], const complex float B[N][K]) { blas_cgemm(CblasNoTrans, CblasNoTrans, M, N, K, 1., M, A, K, B, 0., M, C); } void (blas_csyrk)(char uplo, char trans, long N, long K, const complex float alpha, long lda, const complex float A[][lda], complex float beta, long ldc, complex float C[][ldc]) { assert('U' == uplo); assert(('T' == trans) || ('N' == trans)); cblas_csyrk(CblasColMajor, CblasUpper, ('T' == trans) ? CblasTrans : CblasNoTrans, N, K, (void*)&alpha, (void*)A, lda, (void*)&beta, (void*)C, ldc); } bart-0.5.00/src/num/blas.h000066400000000000000000000011461353046746100152170ustar00rootroot00000000000000 #include #include "misc/misc.h" extern void blas_matrix_multiply(long M, long N, long K, complex float C[N][M], const complex float A[K][M], const complex float B[N][K]); extern void blas_cgemm(char transa, char transb, long M, long N, long K, const complex float alpha, long lda, const complex float A[M][lda], long ldb, const complex float B[K][ldb], const complex float beta, long ldc, complex float C[M][ldc]); extern void blas_csyrk(char uplow, char trans, long N, long K, complex float alpha, long lda, const complex float A[*][lda], complex float beta, long ldc, complex float C[*][ldc]); bart-0.5.00/src/num/blockproc.c000066400000000000000000000263371353046746100162600ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Frank Ong * */ #include #include #include #include #include #include "misc/misc.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "blockproc.h" float lineproc2( unsigned int D, const long dims[D], const long blkdims[D], const long line_dims[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), const long ostrs[D], complex float* dst, const long istrs[D], const complex float* src ) { // Get number of blocks per dimension long nblocks[D]; long shifts[D]; for (unsigned int i = 0; i < D; i++) { nblocks[i] = dims[i] - blkdims[i] + 1; shifts[i] = ( dims[i] - nblocks[i] * line_dims[i]) / 2; } long line_strs[D]; md_calc_strides( D, line_strs, line_dims, CFL_SIZE ); long numblocks = md_calc_size( D, nblocks ); float info = 0; // Loop over blocks complex float* blk = md_alloc_sameplace(D, blkdims, sizeof( complex float ), src); complex float* line = md_alloc_sameplace(D, line_dims, sizeof( complex float ), src); for (long b = 0; b < numblocks; b++) { // Get block position and actual block size long blkpos[D]; long linepos[D]; long ind = b; for ( unsigned int i = 0; i < D; i++) { long blkind = ind % nblocks[i]; blkpos[i] = blkind; linepos[i] = blkind + shifts[i]; ind = (ind - blkind) / nblocks[i]; } long blkstrs[D]; md_calc_strides( D, blkstrs, blkdims, CFL_SIZE ); // Extract block md_copy_block2( D, blkpos, blkdims, blkstrs, blk, dims, istrs, src, sizeof(complex float) ); // Process block info += op( data, blkdims, line, blk ); // Put back block md_copy_block2( D, linepos, dims, ostrs, dst, line_dims, line_strs, line, sizeof( complex float )); } md_free( blk ); md_free( line ); return info; } float lineproc( unsigned int D, const long dims[D], const long blkdims[D], const long line_dims[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), complex float* dst, const complex float* src ) { long strs[D]; md_calc_strides( D, strs, dims, CFL_SIZE ); return lineproc2( D, dims, blkdims, line_dims, data, op, strs, dst, strs, src ); } float blockproc_shift_mult2( unsigned int D, const long dims[D], const long blkdims[D], const long shifts[D], const long mult[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), const long ostrs[D], complex float* dst, const long istrs[D], const complex float* src ) { float info = 0; long pos[D]; for (unsigned int i = 0; i < D; i++) { pos[i] = shifts[i]; while (pos[i] < 0) pos[i] += dims[i]; } unsigned int i = 0; while ((i < D) && (0 == pos[i])) i++; if (D == i) { info += blockproc2( D, dims, blkdims, data, op, ostrs, dst, istrs, src ); return info; } long shift = pos[i]; assert(shift != 0); long dim0[D]; long dim1[D]; long dim2[D]; long dim3[D]; md_copy_dims(D, dim0, dims); md_copy_dims(D, dim1, dims); md_copy_dims(D, dim2, dims); md_copy_dims(D, dim3, dims); dim0[i] = shift - (shift/mult[i]) * mult[i]; dim1[i] = (shift/mult[i]) * mult[i]; dim2[i] = ((dims[i] - shift) / mult[i]) * mult[i]; dim3[i] = dims[i] - (((dims[i] - shift) / mult[i]) * mult[i]) - shift; long off0 = 0; long off1 = off0 + dim0[i] * ostrs[i] / CFL_SIZE; long off2 = off1 + dim1[i] * ostrs[i] / CFL_SIZE; long off3 = off2 + dim2[i] * ostrs[i] / CFL_SIZE; pos[i] = 0; info += blockproc_shift_mult2( D, dim0, blkdims, pos, mult, data, op, ostrs, dst + off0, istrs, src + off0 ); info += blockproc_shift_mult2( D, dim1, blkdims, pos, mult, data, op, ostrs, dst + off1, istrs, src + off1 ); info += blockproc_shift_mult2( D, dim2, blkdims, pos, mult, data, op, ostrs, dst + off2, istrs, src + off2 ); info += blockproc_shift_mult2( D, dim3, blkdims, pos, mult, data, op, ostrs, dst + off3, istrs, src + off3 ); return info; } float blockproc_shift_mult( unsigned int D, const long dims[D], const long blkdims[D], const long shifts[D], const long mult[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), complex float* dst, const complex float* src ) { long strs[D]; md_calc_strides( D, strs, dims, CFL_SIZE ); return blockproc_shift_mult2( D, dims, blkdims, shifts, mult, data, op, strs, dst, strs, src ); } float blockproc_shift2( unsigned int D, const long dims[D], const long blkdims[D], const long shifts[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), const long ostrs[D], complex float* dst, const long istrs[D], const complex float* src ) { float info = 0; long pos[D]; for (unsigned int i = 0; i < D; i++) { pos[i] = shifts[i]; while (pos[i] < 0) pos[i] += dims[i]; } unsigned int i = 0; while ((i < D) && (0 == pos[i])) i++; if (D == i) { info += blockproc2( D, dims, blkdims, data, op, ostrs, dst, istrs, src ); return info; } long shift = pos[i]; assert(shift != 0); long dim1[D]; long dim2[D]; md_copy_dims(D, dim1, dims); md_copy_dims(D, dim2, dims); dim1[i] = shift; dim2[i] = dims[i] - shift; pos[i] = 0; info += blockproc_shift2( D, dim1, blkdims, pos, data, op, ostrs, dst, istrs, src ); info += blockproc_shift2( D, dim2, blkdims, pos, data, op, ostrs, dst + dim1[i]*ostrs[i]/CFL_SIZE, istrs, src + dim1[i]*istrs[i]/CFL_SIZE ); return info; } float blockproc_shift( unsigned int D, const long dims[D], const long blkdims[D], const long shifts[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), complex float* dst, const complex float* src ) { long strs[D]; md_calc_strides( D, strs, dims, CFL_SIZE ); return blockproc_shift2( D, dims, blkdims, shifts, data, op, strs, dst, strs, src ); } float blockproc_circshift( unsigned int D, const long dims[D], const long blkdims[D], const long shifts[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), complex float* dst, const complex float* src ) { complex float* tmp = md_alloc( D, dims, CFL_SIZE ); long unshifts[D]; for (unsigned int i = 0; i < D; i++) unshifts[i] = -shifts[i]; md_circ_shift( D, dims, shifts, tmp, src, CFL_SIZE ); float info = blockproc( D, dims, blkdims, data, op, tmp, tmp ); md_circ_shift( D, dims, unshifts, dst, tmp, CFL_SIZE ); md_free( tmp ); return info; } float blockproc2( unsigned int D, const long dims[D], const long blkdims[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), const long ostrs[D], complex float* dst, const long istrs[D], const complex float* src ) { // Get number of blocks per dimension long nblocks[D]; for (unsigned int i = 0; i < D; i++) { nblocks[i] = (float) ( dims[i] + blkdims[i] - 1 ) / (float) blkdims[i]; } long numblocks = md_calc_size( D, nblocks ); float info = 0; // Loop over blocks complex float* blk = md_alloc_sameplace(D, blkdims, sizeof( complex float ), src); for (long b = 0; b < numblocks; b++) { // Get block position and actual block size long blkpos[D]; long blkdims_b[D]; // actual block size long ind = b; for ( unsigned int i = 0; i < D; i++) { long blkind = ind % nblocks[i]; blkpos[i] = blkind * blkdims[i]; ind = (ind - blkind) / nblocks[i]; blkdims_b[i] = MIN( dims[i] - blkpos[i], blkdims[i] ); } long blkstrs[D]; md_calc_strides( D, blkstrs, blkdims_b, CFL_SIZE ); // Extract block md_copy_block2( D, blkpos, blkdims_b, blkstrs, blk, dims, istrs, src, sizeof(complex float) ); // Process block info += op( data, blkdims_b, blk, blk ); // Put back block md_copy_block2( D, blkpos, dims, ostrs, dst, blkdims_b, blkstrs, blk, sizeof( complex float )); } md_free( blk ); return info; } float blockproc( unsigned int D, const long dims[D], const long blkdims[D], const void* data, float (*op)(const void* data, const long blkdims[D], complex float* dst, const complex float* src), complex float* dst, const complex float* src ) { long strs[D]; md_calc_strides( D, strs, dims, CFL_SIZE ); return blockproc2( D, dims, blkdims, data, op, strs, dst, strs, src ); } float stackproc2( unsigned int D, const long dims[D], const long blkdims[D], unsigned int stkdim, const void* data, float (*op)(const void* data, const long stkdims[D], complex float* dst, const complex float* src), const long ostrs[D], complex float* dst, const long istrs[D], const complex float* src ) { // Get number of blocks per dimension long nblocks[D]; for (unsigned int i = 0; i < D; i++) { nblocks[i] = (float) ( dims[i] + blkdims[i] - 1 ) / (float) blkdims[i]; } long numblocks = md_calc_size( D, nblocks ); float info = 0; // Initialize stack long stkdims[D]; md_copy_dims( D, stkdims, blkdims ); stkdims[stkdim] = numblocks; long stkstrs[D]; md_calc_strides( D, stkstrs, stkdims, CFL_SIZE ); long stkstr1[D]; md_calc_strides( D, stkstr1, stkdims, 1 ); complex float* stk = md_alloc(D, stkdims, sizeof( complex float )); md_clear( D, stkdims, stk, sizeof( complex float ) ); // Loop over blocks and stack them up for (long b = 0; b < numblocks; b++) { // Get block position and actual block size long blkpos[D]; long blkdims_b[D]; // actual block size long ind = b; for ( unsigned int i = 0; i < D; i++) { long blkind = ind % nblocks[i]; blkpos[i] = blkind * blkdims[i]; ind = (ind - blkind) / nblocks[i]; blkdims_b[i] = MIN( dims[i] - blkpos[i], blkdims[i] ); } long blkstrs[D]; md_calc_strides( D, blkstrs, blkdims_b, CFL_SIZE ); // Extract block and put in stack md_copy_block2( D, blkpos, blkdims_b, blkstrs, stk + stkstr1[stkdim] * b, dims, istrs, src, sizeof(complex float) ); } long blkstrs[D]; md_calc_strides( D, blkstrs, blkdims, CFL_SIZE ); // Process block info = op( data, stkdims, stk, stk ); // Put back block for (long b = 0; b < numblocks; b++) { // Get block position and actual block size long blkpos[D]; long blkdims_b[D]; // actual block size long ind = b; for ( unsigned int i = 0; i < D; i++) { long blkind = ind % nblocks[i]; blkpos[i] = blkind * blkdims[i]; ind = (ind - blkind) / nblocks[i]; blkdims_b[i] = MIN( dims[i] - blkpos[i], blkdims[i] ); } long blkstrs[D]; md_calc_strides( D, blkstrs, blkdims_b, CFL_SIZE ); // Put back block md_copy_block2( D, blkpos, dims, ostrs, dst, blkdims_b, blkstrs, stk + stkstr1[stkdim] * b, sizeof( complex float )); } // Free stack md_free( stk ); return info; } float stackproc( unsigned int D, const long dims[D], const long blkdims[D], unsigned int stkdim, const void* data, float (*op)(const void* data, const long stkdims[D], complex float* dst, const complex float* src), complex float* dst, const complex float* src ) { long strs[D]; md_calc_strides( D, strs, dims, CFL_SIZE ); return stackproc2( D, dims, blkdims, stkdim, data, op, strs, dst, strs, src ); } bart-0.5.00/src/num/blockproc.h000066400000000000000000000077121353046746100162610ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __BLOCKPROC #define __BLOCKPROC #include "misc/cppwrap.h" extern float lineproc2(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long line_dims[__VLA(D)], const void * data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), const long ostrs[__VLA(D)], complex float* dst, const long istrs[__VLA(D)], const complex float* src); extern float lineproc(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long line_dims[__VLA(D)], const void * data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), complex float* dst, const complex float* src); extern float blockproc2(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const void * data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), const long ostrs[__VLA(D)], complex float* dst, const long istrs[__VLA(D)], const complex float* src); extern float blockproc(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const void * data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), complex float* dst, const complex float* src); extern float blockproc_shift2(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long shifts[__VLA(D)], const void* data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), const long ostrs[__VLA(D)], complex float* dst, const long istrs[__VLA(D)], const complex float* src); extern float blockproc_shift(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long shifts[__VLA(D)], const void* data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), complex float* dst, const complex float* src); extern float blockproc_circshift(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long shifts[__VLA(D)], const void* data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), complex float* dst, const complex float* src); extern float blockproc_shift_mult2(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long shifts[__VLA(D)], const long mult[__VLA(D)], const void* data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), const long ostrs[__VLA(D)], complex float* dst, const long istrs[__VLA(D)], const complex float* src); extern float blockproc_shift_mult(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], const long shifts[__VLA(D)], const long mult[__VLA(D)], const void* data, float (*op)(const void* data, const long blkdims[__VLA(D)], complex float* dst, const complex float* src), complex float* dst, const complex float* src); extern float stackproc2(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], unsigned int stkdim, const void* data, float (*op)(const void* data, const long stkdims[__VLA(D)], complex float* dst, const complex float* src), const long ostrs[__VLA(D)], complex float* dst, const long istrs[__VLA(D)], const complex float* src); extern float stackproc(unsigned int D, const long dims[__VLA(D)], const long blkdims[__VLA(D)], unsigned int stkdim, const void* data, float (*op)(const void* data, const long stkdims[__VLA(D)], complex float* dst, const complex float* src), complex float* dst, const complex float* src); #include "misc/cppwrap.h" #endif bart-0.5.00/src/num/casorati.c000066400000000000000000000077341353046746100161070ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker * 2014 Frank Ong */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "casorati.h" static void calc_casorati_geom(unsigned int N, long dimc[2 * N], long str2[2 * N], const long dimk[N], const long dim[N], const long str[N]) { for (unsigned int i = 0; i < N; i++) { assert(dim[i] >= dimk[i]); dimc[i + 0] = dim[i] - dimk[i] + 1; // number of shifted blocks dimc[i + N] = dimk[i]; // size of blocks str2[i + N] = str[i]; // by having the same strides str2[i + 0] = str[i]; // we can address overlapping blocks } } void casorati_dims(unsigned int N, long odim[2], const long dimk[N], const long dim[N]) { long dimc[2 * N]; for (unsigned int i = 0; i < N; i++) { assert(dim[i] >= dimk[i]); dimc[i + 0] = dim[i] - dimk[i] + 1; // number of shifted blocks dimc[i + N] = dimk[i]; // size of blocks } odim[0] = md_calc_size(N, dimc + 0); odim[1] = md_calc_size(N, dimc + N); } void casorati_matrix(unsigned int N, const long dimk[N], const long odim[2], complex float* optr, const long dim[N], const long str[N], const complex float* iptr) { long str2[2 * N]; long strc[2 * N]; long dimc[2 * N]; calc_casorati_geom(N, dimc, str2, dimk, dim, str); assert(odim[0] == md_calc_size(N, dimc + 0)); // all shifts are collapsed assert(odim[1] == md_calc_size(N, dimc + N)); // linearized size of a block md_calc_strides(2 * N, strc, dimc, CFL_SIZE); md_copy2(2 * N, dimc, strc, optr, str2, iptr, CFL_SIZE); } void casorati_matrixH(unsigned int N, const long dimk[N], const long dim[N], const long str[N], complex float* optr, const long odim[2], const complex float* iptr) { long str2[2 * N]; long strc[2 * N]; long dimc[2 * N]; calc_casorati_geom(N, dimc, str2, dimk, dim, str); assert(odim[0] == md_calc_size(N, dimc)); assert(odim[1] == md_calc_size(N, dimc + N)); md_clear(N, dim, optr, CFL_SIZE); md_calc_strides(2 * N, strc, dimc, CFL_SIZE); md_zadd2(2 * N, dimc, str2, optr, str2, optr, strc, iptr); } static void calc_basorati_geom(unsigned int N, long dimc[2 * N], long str2[2 * N], const long dimk[N], const long dim[N], const long str[N]) { for (unsigned int i = 0; i < N; i++) { dimc[i + 0] = dimk[i]; // size of blocks dimc[i + N] = dim[i] / dimk[i]; // number of shifted blocks str2[i + 0] = str[i]; str2[i + N] = str[i] * dimk[i]; } } void basorati_dims(unsigned int N, long odim[2], const long dimk[N], const long dim[N]) { long dimc[2 * N]; for (unsigned int i = 0; i < N; i++) { assert(0 == dim[i] % dimk[i]); dimc[i + 0] = dimk[i]; // size of blocks dimc[i + N] = dim[i] / dimk[i]; // number of shifted blocks } odim[0] = md_calc_size(N, dimc + 0); odim[1] = md_calc_size(N, dimc + N); } void basorati_matrix(unsigned int N, const long dimk[N], const long odim[2], complex float* optr, const long dim[N], const long str[N], const complex float* iptr) { long str2[2 * N]; long strc[2 * N]; long dimc[2 * N]; calc_basorati_geom(N, dimc, str2, dimk, dim, str); assert(odim[0] == md_calc_size(N, dimc + 0)); // all shifts are collapsed assert(odim[1] == md_calc_size(N, dimc + N)); // linearized size of a block md_calc_strides(2 * N, strc, dimc, CFL_SIZE); md_copy2(2 * N, dimc, strc, optr, str2, iptr, CFL_SIZE); } void basorati_matrixH(unsigned int N, const long dimk[N], const long dim[N], const long str[N], complex float* optr, const long odim[2], const complex float* iptr) { long str2[2 * N]; long strc[2 * N]; long dimc[2 * N]; calc_basorati_geom(N, dimc, str2, dimk, dim, str); assert(odim[0] == md_calc_size(N, dimc)); assert(odim[1] == md_calc_size(N, dimc + N)); md_calc_strides(2 * N, strc, dimc, CFL_SIZE); md_copy2(2 * N, dimc, str2, optr, strc, iptr, CFL_SIZE); } bart-0.5.00/src/num/casorati.h000066400000000000000000000023501353046746100161010ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" extern void casorati_dims(unsigned int N, long odim[2], const long dimk[__VLA(N)], const long dims[__VLA(N)]); extern void casorati_matrix(unsigned int N, const long dimk[__VLA(N)], const long odim[2], _Complex float* optr, const long dim[__VLA(N)], const long str[__VLA(N)], const _Complex float* iptr); extern void casorati_matrixH(unsigned int N, const long dimk[__VLA(N)], const long dim[__VLA(N)], const long str[__VLA(N)], _Complex float* optr, const long odim[2], const _Complex float* iptr); extern void basorati_dims(unsigned int N, long odim[2], const long dimk[__VLA(N)], const long dims[__VLA(N)]); extern void basorati_matrix(unsigned int N, const long dimk[__VLA(N)], const long odim[2], _Complex float* optr, const long dim[__VLA(N)], const long str[__VLA(N)], const _Complex float* iptr); extern void basorati_matrixH(unsigned int N, const long dimk[__VLA(N)], const long dim[__VLA(N)], const long str[__VLA(N)], _Complex float* optr, const long odim[2], const _Complex float* iptr); #include "misc/cppwrap.h" bart-0.5.00/src/num/chebfun.c000066400000000000000000000101461353046746100157030ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include #include #include #include "num/fft.h" #include "num/flpmath.h" #include "misc/misc.h" #include "num/chebfun.h" static void fft1(int N, complex float tmp[N], const complex float ext[N]) { fft(1, (long[1]){ N }, 1, tmp, ext); md_zsmul(1, (long[1]){ N }, tmp, tmp, 1. / sqrt((double)N)); } static void ifft1(int N, complex float tmp[N], const complex float ext[N]) { ifft(1, (long[1]){ N }, 1, tmp, ext); md_zsmul(1, (long[1]){ N }, tmp, tmp, 1. / sqrt((double)N)); } void chebpoly(int N, float coeff[N], const float val[N]) { complex float ext[(N - 1) * 2]; complex float tmp[(N - 1) * 2]; for (int i = 0; i < N - 1; i++) ext[i] = val[i]; for (int i = 0; i < N - 1; i++) ext[N - 1 + i] = val[N - 1 - i]; fft1((N - 1) * 2, tmp, ext); for (int i = 0; i < N; i++) coeff[i] = crealf(tmp[i]) * sqrt((N - 1) * 2) / (N - 1); // strange? coeff[0] /= 2.; coeff[N - 1] /= 2.; } void chebinv(int N, float val[N], const float coeff[N]) { complex float ext[(N - 1) * 2]; complex float tmp[(N - 1) * 2]; for (int i = 0; i < N; i++) ext[i] = coeff[i] / sqrt((N - 1) * 2) * (N - 1); for (int i = N; i < (N - 1) * 2; i++) ext[i] = 0.; ifft1((N - 1) * 2, tmp, ext); for (int i = 0; i < N; i++) val[i] = crealf(tmp[i]) * 2.; } static void resample(int A, int B, float dst[A], const float src[B]) { for (int i = 0; i < A; i++) dst[i] = 0.; for (int i = 0; i < B; i++) dst[i % A] = src[i]; } float chebeval(float x, int N, const float pval[N]) { float norm = 0.; float val = 0.; for (int i = 0; i < N; i++) { float dist = x - cosf(M_PI * (float)i / (float)(N - 1)); if (0. == dist) return pval[i]; float weight = ((0 == i % 2) ? 1. : -1.) / dist; if ((0 == i) || (N - 1 == i)) weight /= 2.; norm += weight; val += weight * pval[i]; } return val / norm; } void chebadd(int A, int B, float dst[(A > B) ? A : B], const float src1[A], const float src2[B]) { int N = (A > B) ? A : B; float tmp1[N]; float tmp2[N]; resample(N, A, tmp1, src1); resample(N, B, tmp2, src2); for (int i = 0; i < N; i++) dst[i] = tmp1[i] + tmp2[i]; } void chebmul(int A, int B, float dst[A + B], const float src1[A], const float src2[B]) { int N = A + B; float tmp1[N]; float tmp2[N]; resample(N, A, tmp1, src1); resample(N, B, tmp2, src2); float val1[N]; float val2[N]; chebinv(N, val1, tmp1); chebinv(N, val2, tmp2); for (int i = 0; i < N; i++) val1[i] *= val2[i]; chebpoly(N, dst, val1); } float chebint(int N, const float coeff[N]) { double sum = 0.; for (int i = 0; i < N; i += 2) sum += coeff[i] * 2. / (1. - (float)(i * i)); return sum; } void chebindint(int N, float dst[N + 1], const float src[N]) { for (int i = 0; i < N + 1; i++) dst[i] = 0; dst[1] += src[0]; dst[2] += src[1] / 4.; for (int i = 2; i < N; i++) { dst[i - 1] -= src[i] / (2. * (i - 1)); dst[i + 1] += src[i] / (2. * (i + 1)); } } void chebdiff(int N, float dst[N - 1], const float src[N]) { dst[N - 2] = 2. * (N - 1) * src[N - 1]; dst[N - 3] = 2. * (N - 2) * src[N - 2]; for (int i = N - 4; i > 0; i--) dst[i] = dst[i + 2] + 2. * (i + 1) * src[i + 1]; dst[0] = dst[2] / 2. + src[1]; } void chebfun2(int N, float coeff[N], float (*fun)(float x)) { float val[N]; for (int i = 0; i < N; i++) val[i] = fun(cosf(M_PI * (float)i / (float)(N - 1))); chebpoly(N, coeff, val); } float* chebfun(int* NP, float (*fun)(float x)) { int N = 129; while(true) { float coeff[N]; chebfun2(N, coeff, fun); int maxind = 0; for (int i = 0; i < N; i++) if (fabsf(coeff[maxind]) < fabsf(coeff[i])) maxind = i; if (coeff[N - 1] < 2. * FLT_EPSILON * coeff[maxind]) { while ( (coeff[N - 1] < 2. * FLT_EPSILON * coeff[maxind]) && (coeff[N - 2] < 2. * FLT_EPSILON * coeff[maxind])) N -= 2; float* out = xmalloc(sizeof(float) * N); for (int i = 0; i < N; i++) out[i] = coeff[i]; *NP = N; return out; } N = (N - 1) * 2 + 1; } } bart-0.5.00/src/num/chebfun.h000066400000000000000000000012761353046746100157140ustar00rootroot00000000000000 extern float* chebfun(int* NP, float (*fun)(float x)); extern void chebfun2(int N, float coeff[N], float (*fun)(float x)); extern void chebpoly(int N, float coeff[N], const float val[N]); extern void chebinv(int N, float val[N], const float coeff[N]); extern void chebadd(int A, int B, float dst[(A > B) ? A : B], const float src1[A], const float src2[B]); extern void chebmul(int A, int B, float dst[A + B], const float src1[A], const float src2[B]); extern float chebint(int N, const float coeff[N]); extern float chebeval(float x, int N, const float pval[N]); extern void chebdiff(int N, float dst[N - 1], const float src[N]); extern void chebindint(int N, float dst[N + 1], const float src[N]); bart-0.5.00/src/num/conv.c000066400000000000000000000171451353046746100152440ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2017 Martin Uecker */ #include #include #include #include "num/fft.h" #include "num/multind.h" #include "num/flpmath.h" #include "misc/misc.h" #include "conv.h" struct conv_plan { enum conv_mode cmode; enum conv_type ctype; int N; unsigned int flags; struct fft_plan_s* fft_plan; long* idims; long* odims; long* dims; long* dims1; long* dims2; long* str1; long* str2; long* kdims; long* kstr; complex float* kernel; }; struct conv_plan* conv_plan(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[N], const long idims1[N], const long idims2[N], const complex float* src2) { PTR_ALLOC(struct conv_plan, plan); plan->N = N; plan->flags = flags; plan->cmode = cmode; plan->ctype = ctype; plan->dims = *TYPE_ALLOC(long[N]); plan->dims1 = *TYPE_ALLOC(long[N]); plan->dims2 = *TYPE_ALLOC(long[N]); plan->kdims = *TYPE_ALLOC(long[N]); plan->idims = *TYPE_ALLOC(long[N]); plan->odims = *TYPE_ALLOC(long[N]); complex float U = 1.; for (int i = 0; i < N; i++) { plan->idims[i] = idims1[i]; plan->odims[i] = odims[i]; if (MD_IS_SET(flags, i)) { assert(idims2[i] <= idims1[i]); if (cmode == CONV_SYMMETRIC) { assert((0 == idims1[i] % 2) && (1 == idims2[i] % 2)); if (1 == (idims1[i] / 2) % 2) U *= -1.i; } switch (ctype) { case CONV_CYCLIC: assert(odims[i] == idims1[i]); plan->dims1[i] = idims1[i]; plan->dims2[i] = odims[i]; break; case CONV_TRUNCATED: assert(odims[i] == idims1[i]); plan->dims1[i] = idims1[i] + idims2[i] - 1; plan->dims2[i] = odims[i] + idims2[i] - 1; break; case CONV_VALID: plan->dims1[i] = odims[i] + idims2[i] - 1; plan->dims2[i] = odims[i] + idims2[i] - 1; assert(idims1[i] == plan->dims1[i]); break; case CONV_EXTENDED: plan->dims1[i] = idims1[i] + idims2[i] - 1; plan->dims2[i] = idims1[i] + idims2[i] - 1; assert(odims[i] == plan->dims2[i]); } plan->kdims[i] = (1 == idims2[i]) ? 1 : plan->dims1[i]; U *= (float)plan->dims1[i]; } else { // O I K: // X X X // X X 1 // X 1 X // X 1 1 (inefficient) // 1 X X assert((1 == idims1[i]) || (idims1[i] == odims[i]) || (idims1[i] == idims2[i])); assert((1 == idims2[i]) || (idims2[i] == odims[i]) || (idims2[i] == idims1[i])); assert((1 == odims[i]) || (idims2[i] == odims[i]) || (idims1[i] == odims[i])); plan->dims1[i] = idims1[i]; plan->dims2[i] = odims[i]; plan->kdims[i] = idims2[i]; } plan->dims[i] = MAX(plan->dims1[i], plan->dims2[i]); } plan->str1 = *TYPE_ALLOC(long[N]); plan->str2 = *TYPE_ALLOC(long[N]); plan->kstr = *TYPE_ALLOC(long[N]); md_calc_strides(N, plan->str1, plan->dims1, CFL_SIZE); md_calc_strides(N, plan->str2, plan->dims2, CFL_SIZE); md_calc_strides(N, plan->kstr, plan->kdims, CFL_SIZE); plan->kernel = md_alloc_sameplace(N, plan->kdims, CFL_SIZE, src2); switch (cmode) { case CONV_SYMMETRIC: md_resize_center(N, plan->kdims, plan->kernel, idims2, src2, CFL_SIZE); ifft(N, plan->kdims, flags, plan->kernel, plan->kernel); fftmod(N, plan->kdims, flags, plan->kernel, plan->kernel); break; case CONV_CAUSAL: md_resize(N, plan->kdims, plan->kernel, idims2, src2, CFL_SIZE); ifft(N, plan->kdims, flags, plan->kernel, plan->kernel); break; case CONV_ANTICAUSAL: md_resize(N, plan->kdims, plan->kernel, idims2, src2, CFL_SIZE); fft(N, plan->kdims, flags, plan->kernel, plan->kernel); break; default: assert(0); } md_zsmul(N, plan->kdims, plan->kernel, plan->kernel, 1. / U); // plan->fftplan = fft_plan(N, plan->dims, plan->flags); return PTR_PASS(plan); } void conv_free(struct conv_plan* plan) { md_free(plan->kernel); // fft_free_plan xfree(plan->dims); xfree(plan->dims1); xfree(plan->dims2); xfree(plan->kdims); xfree(plan->str1); xfree(plan->str2); xfree(plan->kstr); xfree(plan->idims); xfree(plan->odims); xfree(plan); } static void conv_cyclic(struct conv_plan* plan, complex float* dst, const complex float* src1) { // FIXME: optimize tmp away when possible complex float* tmp = md_alloc_sameplace(plan->N, plan->dims1, CFL_SIZE, plan->kernel); ifft(plan->N, plan->dims1, plan->flags, tmp, src1); md_clear(plan->N, plan->dims2, dst, CFL_SIZE); md_zfmac2(plan->N, plan->dims, plan->str2, dst, plan->str1, tmp, plan->kstr, plan->kernel); // md_zmul2(plan->N, plan->dims, plan->str2, dst, plan->str1, tmp, plan->kstr, plan->kernel); fft(plan->N, plan->dims2, plan->flags, dst, dst); md_free(tmp); } static void conv_cyclicH(struct conv_plan* plan, complex float* dst, const complex float* src1) { complex float* tmp = md_alloc_sameplace(plan->N, plan->dims1, CFL_SIZE, plan->kernel); ifft(plan->N, plan->dims2, plan->flags, tmp, src1); md_clear(plan->N, plan->dims1, dst, CFL_SIZE); md_zfmacc2(plan->N, plan->dims, plan->str1, dst, plan->str2, tmp, plan->kstr, plan->kernel); //md_zmulc2(plan->N, plan->dims1, plan->str1, dst, plan->str2, tmp, plan->kstr, plan->kernel); fft(plan->N, plan->dims1, plan->flags, dst, dst); md_free(tmp); } void conv_exec(struct conv_plan* plan, complex float* dst, const complex float* src1) { bool crop = (CONV_SYMMETRIC == plan->cmode); bool pre = (CONV_TRUNCATED == plan->ctype) || (CONV_EXTENDED == plan->ctype); bool post = (CONV_TRUNCATED == plan->ctype) || (CONV_VALID == plan->ctype); complex float* tmp = NULL; if (pre || post) { tmp = md_alloc_sameplace(plan->N, plan->dims1, CFL_SIZE, plan->kernel); } if (pre) (crop ? md_resize_center : md_resize)(plan->N, plan->dims1, tmp, plan->idims, src1, CFL_SIZE); conv_cyclic(plan, post ? tmp : dst, pre ? tmp : src1); if (post) (crop ? md_resize_center : md_resize)(plan->N, plan->odims, dst, plan->dims2, tmp, CFL_SIZE); if (pre || post) md_free(tmp); } void conv_adjoint(struct conv_plan* plan, complex float* dst, const complex float* src1) { bool crop = (CONV_SYMMETRIC == plan->cmode); bool post = (CONV_TRUNCATED == plan->ctype) || (CONV_EXTENDED == plan->ctype); bool pre = (CONV_TRUNCATED == plan->ctype) || (CONV_VALID == plan->ctype); complex float* tmp = NULL; if (pre || post) { tmp = md_alloc_sameplace(plan->N, plan->dims1, CFL_SIZE, plan->kernel); } if (pre) (crop ? md_resize_center : md_resize)(plan->N, plan->dims2, tmp, plan->odims, src1, CFL_SIZE); conv_cyclicH(plan, post ? tmp : dst, pre ? tmp : src1); if (post) (crop ? md_resize_center : md_resize)(plan->N, plan->idims, dst, plan->dims1, tmp, CFL_SIZE); if (pre || post) md_free(tmp); } void conv(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[N], complex float* dst, const long idims1[N], const complex float* src1, const long idims2[N], const complex float* src2) { struct conv_plan* plan = conv_plan(N, flags, ctype, cmode, odims, idims1, idims2, src2); conv_exec(plan, dst, src1); conv_free(plan); } void convH(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[N], complex float* dst, const long idims1[N], const complex float* src1, const long idims2[N], const complex float* src2) { struct conv_plan* plan = conv_plan(N, flags, ctype, cmode, idims1, odims, idims2, src2); // idims1 <-> odims conv_adjoint(plan, dst, src1); conv_free(plan); } bart-0.5.00/src/num/conv.h000066400000000000000000000027421353046746100152460ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2012-10-28 Martin Uecker */ #include #include "misc/cppwrap.h" #ifndef __CONV_ENUMS #define __CONV_ENUMS enum conv_mode { CONV_SYMMETRIC, CONV_CAUSAL, CONV_ANTICAUSAL }; enum conv_type { CONV_CYCLIC, CONV_TRUNCATED, CONV_VALID, CONV_EXTENDED }; #endif struct conv_plan; extern struct conv_plan* conv_plan(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[__VLA(N)], const long idims1[__VLA(N)], const long idims2[__VLA(N)], const complex float* src2); extern void conv_exec(struct conv_plan* plan, complex float* dst, const complex float* src1); extern void conv_adjoint(struct conv_plan* plan, complex float* dst, const complex float* src1); extern void conv_free(struct conv_plan* plan); extern void conv(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[__VLA(N)], complex float* dst, const long idims1[__VLA(N)], const complex float* src1, const long idims2[__VLA(N)], const complex float* src2); extern void convH(int N, unsigned int flags, enum conv_type ctype, enum conv_mode cmode, const long odims[__VLA(N)], complex float* dst, const long idims1[__VLA(N)], const complex float* src1, const long idims2[__VLA(N)], const complex float* src2); #include "misc/cppwrap.h" bart-0.5.00/src/num/convoaa.c000066400000000000000000000432651353046746100157270ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker uecker@eecs.berkeley.edu */ #include #include "misc/misc.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/conv.h" #include "num/vecops.h" #include "convoaa.h" void overlapandadd(int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N], complex float* src2) { long ndims[2 * N]; long L[2 * N]; long ndim2[2 * N]; long ndim3[2 * N]; for (int i = 0; i < N; i++) { assert(0 == dims[i] % blk[i]); assert(dim2[i] <= blk[i]); ndims[i * 2 + 1] = dims[i] / blk[i]; ndims[i * 2 + 0] = blk[i]; L[i * 2 + 1] = dims[i] / blk[i]; L[i * 2 + 0] = blk[i] + dim2[i] - 1; ndim2[i * 2 + 1] = 1; ndim2[i * 2 + 0] = dim2[i]; ndim3[i * 2 + 1] = dims[i] / blk[i] + 1; ndim3[i * 2 + 0] = blk[i]; } complex float* tmp = md_alloc(2 * N, L, CFL_SIZE); // conv_causal_extend(2 * N, L, tmp, ndims, src1, ndim2, src2); conv(2 * N, ~0, CONV_EXTENDED, CONV_CAUSAL, L, tmp, ndims, src1, ndim2, src2); // [------++++|||||||| //long str1[2 * N]; long str2[2 * N]; long str3[2 * N]; //md_calc_strides(2 * N, str1, ndims, 8); md_calc_strides(2 * N, str2, L, 8); md_calc_strides(2 * N, str3, ndim3, 8); md_clear(2 * N, ndim3, dst, CFL_SIZE); md_zadd2(2 * N, L, str3, dst, str3, dst, str2, tmp); md_free(tmp); } void overlapandsave(int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N], complex float* src2) { // [------++++ // [------ long ndims[2 * N]; long L[2 * N]; long ndim2[2 * N]; long ndim3[2 * N]; for (int i = 0; i < N; i++) { assert(0 == dims[i] % blk[i]); assert(dim2[i] <= blk[i]); ndims[i * 2 + 1] = dims[i] / blk[i]; ndims[i * 2 + 0] = blk[i]; L[i * 2 + 1] = dims[i] / blk[i]; L[i * 2 + 0] = blk[i] + dim2[i] - 1; ndim2[i * 2 + 1] = 1; ndim2[i * 2 + 0] = dim2[i]; ndim3[i * 2 + 1] = dims[i] / blk[i] - 0; ndim3[i * 2 + 0] = blk[i]; } complex float* tmp = md_alloc(2 * N, L, CFL_SIZE); long str1[2 * N]; long str2[2 * N]; long str3[2 * N]; md_calc_strides(2 * N, str1, ndims, 8); md_calc_strides(2 * N, str2, L, 8); md_calc_strides(2 * N, str3, ndim3, 8); md_clear(2 * N, L, tmp, 8); md_copy2(2 * N, ndim3, str2, tmp, str1, src1, 8); conv(2 * N, ~0, CONV_VALID, CONV_CAUSAL, ndims, dst, L, tmp, ndim2, src2); md_free(tmp); } #if 0 struct conv_plan* overlapandsave_plan(int N, const long dims[N], const long blk[N], const long dim2[N], complex float* src2) { return conv_plan(2 * N, ~0, CONV_VALID, CONV_CAUSAL, ndims, L, ndim2, src2); } void overlapandsave_exec(struct conv_plan* plan, int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N]) { md_clear(2 * N, L, tmp, 8); md_copy2(2 * N, ndim3, str2, tmp, str1, src1, 8); conv_exec(plan, dst, tmp); xfree(tmp); } #endif void overlapandsave2(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], const complex float* src1, const long dims2[N], const complex float* src2) { long dims1B[N]; long tdims[2 * N]; long nodims[2 * N]; long ndims1[2 * N]; long ndims2[2 * N]; long shift[2 * N]; unsigned int nflags = 0; for (int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { nflags = MD_SET(nflags, 2 * i); assert(1 == dims2[i] % 2); assert(0 == blk[i] % 2); assert(0 == dims1[i] % 2); assert(0 == odims[i] % blk[i]); assert(0 == dims1[i] % blk[i]); assert(dims1[i] == odims[i]); assert(dims2[i] <= blk[i]); assert(dims1[i] >= dims2[i]); // blocked output nodims[i * 2 + 1] = odims[i] / blk[i]; nodims[i * 2 + 0] = blk[i]; // expanded temporary storage tdims[i * 2 + 1] = dims1[i] / blk[i]; tdims[i * 2 + 0] = blk[i] + dims2[i] - 1; // blocked input // ---|---,---,---|--- // + +++ + // + +++ + // resized input dims1B[i] = dims1[i] + 2 * blk[i]; ndims1[i * 2 + 1] = dims1[i] / blk[i] + 2; // do we need two full blocks? ndims1[i * 2 + 0] = blk[i]; shift[i * 2 + 1] = 0; shift[i * 2 + 0] = blk[i] - (dims2[i] - 1) / 2; // kernel ndims2[i * 2 + 1] = 1; ndims2[i * 2 + 0] = dims2[i]; } else { nodims[i * 2 + 1] = 1; nodims[i * 2 + 0] = odims[i]; tdims[i * 2 + 1] = 1; tdims[i * 2 + 0] = dims1[i]; ndims1[i * 2 + 1] = 1; ndims1[i * 2 + 0] = dims1[i]; shift[i * 2 + 1] = 0; shift[i * 2 + 0] = 0; dims1B[i] = dims1[i]; ndims2[i * 2 + 1] = 1; ndims2[i * 2 + 0] = dims2[i]; } } complex float* src1B = md_alloc(N, dims1B, CFL_SIZE); md_resize_center(N, dims1B, src1B, dims1, src1, CFL_SIZE); complex float* tmp = md_alloc(2 * N, tdims, CFL_SIZE); long str1[2 * N]; long str2[2 * N]; md_calc_strides(2 * N, str1, ndims1, CFL_SIZE); md_calc_strides(2 * N, str2, tdims, CFL_SIZE); long off = md_calc_offset(2 * N, str1, shift); md_copy2(2 * N, tdims, str2, tmp, str1, ((void*)src1B) + off, CFL_SIZE); md_free(src1B); conv(2 * N, nflags, CONV_VALID, CONV_SYMMETRIC, nodims, dst, tdims, tmp, ndims2, src2); md_free(tmp); } void overlapandsave2H(int N, unsigned int flags, const long blk[N], const long dims1[N], complex float* dst, const long odims[N], const complex float* src1, const long dims2[N], const complex float* src2) { long dims1B[N]; long tdims[2 * N]; long nodims[2 * N]; long ndims1[2 * N]; long ndims2[2 * N]; long shift[2 * N]; unsigned int nflags = 0; for (int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { nflags = MD_SET(nflags, 2 * i); assert(1 == dims2[i] % 2); assert(0 == blk[i] % 2); assert(0 == dims1[i] % 2); assert(0 == odims[i] % blk[i]); assert(0 == dims1[i] % blk[i]); assert(dims1[i] == odims[i]); assert(dims2[i] <= blk[i]); assert(dims1[i] >= dims2[i]); // blocked output nodims[i * 2 + 1] = odims[i] / blk[i]; nodims[i * 2 + 0] = blk[i]; // expanded temporary storage tdims[i * 2 + 1] = dims1[i] / blk[i]; tdims[i * 2 + 0] = blk[i] + dims2[i] - 1; // blocked input // ---|---,---,---|--- // + +++ + // + +++ + // resized input dims1B[i] = dims1[i] + 2 * blk[i]; ndims1[i * 2 + 1] = dims1[i] / blk[i] + 2; // do we need two full blocks? ndims1[i * 2 + 0] = blk[i]; shift[i * 2 + 1] = 0; shift[i * 2 + 0] = blk[i] - (dims2[i] - 1) / 2; // kernel ndims2[i * 2 + 1] = 1; ndims2[i * 2 + 0] = dims2[i]; } else { nodims[i * 2 + 1] = 1; nodims[i * 2 + 0] = odims[i]; tdims[i * 2 + 1] = 1; tdims[i * 2 + 0] = dims1[i]; ndims1[i * 2 + 1] = 1; ndims1[i * 2 + 0] = dims1[i]; shift[i * 2 + 1] = 0; shift[i * 2 + 0] = 0; dims1B[i] = dims1[i]; ndims2[i * 2 + 1] = 1; ndims2[i * 2 + 0] = dims2[i]; } } complex float* tmp = md_alloc(2 * N, tdims, CFL_SIZE); //conv(2 * N, flags, CONV_VALID, CONV_SYMMETRIC, nodims, dst, tdims, tmp, ndims2, src2); convH(2 * N, nflags, CONV_VALID, CONV_SYMMETRIC, tdims, tmp, nodims, src1, ndims2, src2); complex float* src1B = md_alloc(N, dims1B, CFL_SIZE); long str1[2 * N]; long str2[2 * N]; md_calc_strides(2 * N, str1, ndims1, CFL_SIZE); md_calc_strides(2 * N, str2, tdims, CFL_SIZE); long off = md_calc_offset(2 * N, str1, shift); md_clear(N, dims1B, src1B, CFL_SIZE); //md_copy2(2 * N, tdims, str1, ((void*)src1B) + off, str2, tmp, sizeof(complex float));// FIXME: md_zadd2(2 * N, tdims, str1, ((void*)src1B) + off, str1, ((void*)src1B) + off, str2, tmp); md_resize_center(N, dims1, dst, dims1B, src1B, CFL_SIZE); md_free(src1B); md_free(tmp); } void overlapandsave2NE(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], complex float* src1, const long dims2[N], complex float* src2, const long mdims[N], complex float* msk) { long dims1B[N]; long tdims[2 * N]; long nodims[2 * N]; long ndims1[2 * N]; long ndims2[2 * N]; long shift[2 * N]; unsigned int nflags = 0; for (int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { nflags = MD_SET(nflags, 2 * i); assert(1 == dims2[i] % 2); assert(0 == blk[i] % 2); assert(0 == dims1[i] % 2); assert(0 == odims[i] % blk[i]); assert(0 == dims1[i] % blk[i]); assert(dims1[i] == odims[i]); assert(dims2[i] <= blk[i]); assert(dims1[i] >= dims2[i]); // blocked output nodims[i * 2 + 1] = odims[i] / blk[i]; nodims[i * 2 + 0] = blk[i]; // expanded temporary storage tdims[i * 2 + 1] = dims1[i] / blk[i]; tdims[i * 2 + 0] = blk[i] + dims2[i] - 1; // blocked input // ---|---,---,---|--- // + +++ + // + +++ + // resized input dims1B[i] = dims1[i] + 2 * blk[i]; ndims1[i * 2 + 1] = dims1[i] / blk[i] + 2; // do we need two full blocks? ndims1[i * 2 + 0] = blk[i]; shift[i * 2 + 1] = 0; shift[i * 2 + 0] = blk[i] - (dims2[i] - 1) / 2; // kernel ndims2[i * 2 + 1] = 1; ndims2[i * 2 + 0] = dims2[i]; } else { nodims[i * 2 + 1] = 1; nodims[i * 2 + 0] = odims[i]; tdims[i * 2 + 1] = 1; tdims[i * 2 + 0] = dims1[i]; ndims1[i * 2 + 1] = 1; ndims1[i * 2 + 0] = dims1[i]; shift[i * 2 + 1] = 0; shift[i * 2 + 0] = 0; dims1B[i] = dims1[i]; ndims2[i * 2 + 1] = 1; ndims2[i * 2 + 0] = dims2[i]; } } complex float* src1B = md_alloc(N, dims1B, CFL_SIZE); complex float* tmp = md_alloc(2 * N, tdims, CFL_SIZE); complex float* tmpX = md_alloc(N, odims, CFL_SIZE); long str1[2 * N]; long str2[2 * N]; md_calc_strides(2 * N, str1, ndims1, sizeof(complex float)); md_calc_strides(2 * N, str2, tdims, sizeof(complex float)); long off = md_calc_offset(2 * N, str1, shift); md_resize_center(N, dims1B, src1B, dims1, src1, sizeof(complex float)); // we can loop here md_copy2(2 * N, tdims, str2, tmp, str1, ((void*)src1B) + off, sizeof(complex float)); conv(2 * N, nflags, CONV_VALID, CONV_SYMMETRIC, nodims, tmpX, tdims, tmp, ndims2, src2); long ostr[N]; long mstr[N]; md_calc_strides(N, ostr, odims, sizeof(complex float)); md_calc_strides(N, mstr, mdims, sizeof(complex float)); md_zmul2(N, odims, ostr, tmpX, ostr, tmpX, mstr, msk); convH(2 * N, nflags, CONV_VALID, CONV_SYMMETRIC, tdims, tmp, nodims, tmpX, ndims2, src2); md_clear(N, dims1B, src1B, sizeof(complex float)); md_zadd2(2 * N, tdims, str1, ((void*)src1B) + off, str1, ((void*)src1B) + off, str2, tmp); // md_resize_center(N, dims1, dst, dims1B, src1B, sizeof(complex float)); md_free(src1B); md_free(tmpX); md_free(tmp); } void overlapandsave2NEB(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], const complex float* src1, const long dims2[N], const complex float* src2, const long mdims[N], const complex float* msk) { long dims1B[N]; long tdims[2 * N]; long nodims[2 * N]; long ndims2[2 * N]; long nmdims[2 * N]; int e = N; for (int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { assert(1 == dims2[i] % 2); assert(0 == blk[i] % 2); assert(0 == dims1[i] % 2); assert(0 == odims[i] % blk[i]); assert(0 == dims1[i] % blk[i]); assert(dims1[i] == odims[i]); assert(dims2[i] <= blk[i]); assert(dims1[i] >= dims2[i]); assert((1 == mdims[i]) || (mdims[i] == dims1[i])); // blocked output nodims[e] = odims[i] / blk[i]; nodims[i] = blk[i]; // expanded temporary storage tdims[e] = dims1[i] / blk[i]; tdims[i] = blk[i] + dims2[i] - 1; // blocked input // ---|---,---,---|--- // + +++ + // + +++ + if (1 == mdims[i]) { nmdims[2 * i + 1] = 1; nmdims[2 * i + 1] = 1; } else { nmdims[2 * i + 1] = mdims[i] / blk[i]; nmdims[2 * i + 0] = blk[i]; } // resized input // minimal padding dims1B[i] = dims1[i] + (dims2[i] - 1); // kernel ndims2[e] = 1; ndims2[i] = dims2[i]; e++; } else { nodims[i] = odims[i]; tdims[i] = dims1[i]; nmdims[2 * i + 1] = 1; nmdims[2 * i + 0] = mdims[i]; dims1B[i] = dims1[i]; ndims2[i] = dims2[i]; } } int NE = e; //long S = md_calc_size(N, dims1B, 1); long str1[NE]; long str1B[N]; md_calc_strides(N, str1B, dims1B, sizeof(complex float)); e = N; for (int i = 0; i < N; i++) { str1[i] = str1B[i]; if (MD_IS_SET(flags, i)) str1[e++] = str1B[i] * blk[i]; } assert(NE == e); long str2[NE]; md_calc_strides(NE, str2, tdims, sizeof(complex float)); long ostr[NE]; long mstr[NE]; long mstrB[2 * N]; md_calc_strides(NE, ostr, nodims, sizeof(complex float)); md_calc_strides(2 * N, mstrB, nmdims, sizeof(complex float)); e = N; for (int i = 0; i < N; i++) { mstr[i] = mstrB[2 * i + 0]; if (MD_IS_SET(flags, i)) mstr[e++] = mstrB[2 * i + 1]; } assert(NE == e); const complex float* src1B = src1;//! //complex float* src1B = xmalloc(S * sizeof(complex float)); //md_resizec(N, dims1B, src1B, dims1, src1, sizeof(complex float)); // we can loop here assert(NE == N + 3); assert(1 == ndims2[N + 0]); assert(1 == ndims2[N + 1]); assert(1 == ndims2[N + 2]); assert(tdims[N + 0] == nodims[N + 0]); assert(tdims[N + 1] == nodims[N + 1]); assert(tdims[N + 2] == nodims[N + 2]); //complex float* src1C = xmalloc(S * sizeof(complex float)); complex float* src1C = dst; md_clear(N, dims1B, src1C, sizeof(complex float)); // must be done here #pragma omp parallel for collapse(3) for (int k = 0; k < nodims[N + 2]; k++) { for (int j = 0; j < nodims[N + 1]; j++) { for (int i = 0; i < nodims[N + 0]; i++) { complex float* tmp = md_alloc_sameplace(N, tdims, CFL_SIZE, dst); complex float* tmpX = md_alloc_sameplace(N, nodims, CFL_SIZE, dst); long off1 = str1[N + 0] * i + str1[N + 1] * j + str1[N + 2] * k; long off2 = mstr[N + 0] * i + mstr[N + 1] * j + mstr[N + 2] * k; md_copy2(N, tdims, str2, tmp, str1, ((const void*)src1B) + off1, sizeof(complex float)); conv(N, flags, CONV_VALID, CONV_SYMMETRIC, nodims, tmpX, tdims, tmp, ndims2, src2); md_zmul2(N, nodims, ostr, tmpX, ostr, tmpX, mstr, ((const void*)msk) + off2); convH(N, flags, CONV_VALID, CONV_SYMMETRIC, tdims, tmp, nodims, tmpX, ndims2, src2); #pragma omp critical md_zadd2(N, tdims, str1, ((void*)src1C) + off1, str1, ((void*)src1C) + off1, str2, tmp); md_free(tmpX); md_free(tmp); }}} //md_resizec(N, dims1, dst, dims1B, src1C, sizeof(complex float)); //xfree(src1C); //xfree(src1B); } void overlapandsave2HB(int N, unsigned int flags, const long blk[N], const long dims1[N], complex float* dst, const long odims[N], const complex float* src1, const long dims2[N], const complex float* src2, const long mdims[N], const complex float* msk) { long dims1B[N]; long tdims[2 * N]; long nodims[2 * N]; long ndims2[2 * N]; long nmdims[2 * N]; int e = N; for (int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { assert(1 == dims2[i] % 2); assert(0 == blk[i] % 2); assert(0 == dims1[i] % 2); assert(0 == odims[i] % blk[i]); assert(0 == dims1[i] % blk[i]); assert(dims1[i] == odims[i]); assert(dims2[i] <= blk[i]); assert(dims1[i] >= dims2[i]); assert((1 == mdims[i]) || (mdims[i] == dims1[i])); // blocked output nodims[e] = odims[i] / blk[i]; nodims[i] = blk[i]; // expanded temporary storage tdims[e] = dims1[i] / blk[i]; tdims[i] = blk[i] + dims2[i] - 1; // blocked input // ---|---,---,---|--- // + +++ + // + +++ + if (1 == mdims[i]) { nmdims[2 * i + 1] = 1; nmdims[2 * i + 1] = 1; } else { nmdims[2 * i + 1] = mdims[i] / blk[i]; nmdims[2 * i + 0] = blk[i]; } // resized input // minimal padding dims1B[i] = dims1[i] + (dims2[i] - 1); // kernel ndims2[e] = 1; ndims2[i] = dims2[i]; e++; } else { nodims[i] = odims[i]; tdims[i] = dims1[i]; nmdims[2 * i + 1] = 1; nmdims[2 * i + 0] = mdims[i]; dims1B[i] = dims1[i]; ndims2[i] = dims2[i]; } } int NE = e; // long S = md_calc_size(N, dims1B, 1); long str1[NE]; long str1B[N]; md_calc_strides(N, str1B, dims1B, sizeof(complex float)); e = N; for (int i = 0; i < N; i++) { str1[i] = str1B[i]; if (MD_IS_SET(flags, i)) str1[e++] = str1B[i] * blk[i]; } assert(NE == e); long str2[NE]; md_calc_strides(NE, str2, tdims, sizeof(complex float)); long ostr[NE]; long mstr[NE]; long mstrB[2 * N]; md_calc_strides(NE, ostr, nodims, sizeof(complex float)); md_calc_strides(2 * N, mstrB, nmdims, sizeof(complex float)); e = N; for (int i = 0; i < N; i++) { mstr[i] = mstrB[2 * i + 0]; if (MD_IS_SET(flags, i)) mstr[e++] = mstrB[2 * i + 1]; } assert(NE == e); // we can loop here assert(NE == N + 3); assert(1 == ndims2[N + 0]); assert(1 == ndims2[N + 1]); assert(1 == ndims2[N + 2]); assert(tdims[N + 0] == nodims[N + 0]); assert(tdims[N + 1] == nodims[N + 1]); assert(tdims[N + 2] == nodims[N + 2]); //complex float* src1C = xmalloc(S * sizeof(complex float)); complex float* src1C = dst; md_clear(N, dims1B, src1C, CFL_SIZE); // must be done here #pragma omp parallel for collapse(3) for (int k = 0; k < nodims[N + 2]; k++) { for (int j = 0; j < nodims[N + 1]; j++) { for (int i = 0; i < nodims[N + 0]; i++) { complex float* tmp = md_alloc_sameplace(N, tdims, CFL_SIZE, dst); complex float* tmpX = md_alloc_sameplace(N, nodims, CFL_SIZE, dst); long off1 = str1[N + 0] * i + str1[N + 1] * j + str1[N + 2] * k; long off2 = mstr[N + 0] * i + mstr[N + 1] * j + mstr[N + 2] * k; long off3 = ostr[N + 0] * i + ostr[N + 1] * j + ostr[N + 2] * k; md_zmul2(N, nodims, ostr, tmpX, ostr, ((const void*)src1) + off3, mstr, ((const void*)msk) + off2); convH(N, flags, CONV_VALID, CONV_SYMMETRIC, tdims, tmp, nodims, tmpX, ndims2, src2); #pragma omp critical md_zadd2(N, tdims, str1, ((void*)src1C) + off1, str1, ((void*)src1C) + off1, str2, tmp); md_free(tmpX); md_free(tmp); }}} } bart-0.5.00/src/num/convoaa.h000066400000000000000000000034641353046746100157310ustar00rootroot00000000000000 #include extern void overlapandadd(int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N], complex float* src2); extern void overlapandsave(int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N], complex float* src2); extern struct conv_plan* overlapandsave_plan(int N, const long dims[N], const long blk[N], const long dim2[N], complex float* src2); extern void overlapandsave_exec(struct conv_plan* plan, int N, const long dims[N], const long blk[N], complex float* dst, complex float* src1, const long dim2[N]); extern void overlapandsave2(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], const complex float* src1, const long dims2[N], const complex float* src2); extern void overlapandsave2H(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], const complex float* src1, const long dims2[N], const complex float* src2); extern void overlapandsave2NE(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], complex float* src1, const long dims2[N], complex float* src2, const long mdims[N], complex float* msk); struct vec_ops; extern void overlapandsave2NEB(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], const complex float* src1, const long dims2[N], const complex float* src2, const long mdims[N], const complex float* msk); extern void overlapandsave2HB(int N, unsigned int flags, const long blk[N], const long odims[N], complex float* dst, const long dims1[N], const complex float* src1, const long dims2[N], const complex float* src2, const long mdims[N], const complex float* msk); bart-0.5.00/src/num/fft-cuda.c000066400000000000000000000115621353046746100157650ustar00rootroot00000000000000/* Copyright 2013, 2015. The Regents of the University of California. * Copyright 2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * * * Internal interface to the CUFFT library used in fft.c. */ #include #include #include #include "misc/misc.h" #include "num/multind.h" #include "fft-cuda.h" #ifdef USE_CUDA #include #include "num/gpuops.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif struct fft_cuda_plan_s { cufftHandle cufft; struct fft_cuda_plan_s* chain; bool backwards; long batch; long idist; long odist; }; struct iovec { long n; long is; long os; }; static struct fft_cuda_plan_s* fft_cuda_plan0(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], const long istrides[D], bool backwards) { PTR_ALLOC(struct fft_cuda_plan_s, plan); unsigned int N = D; plan->batch = 1; plan->odist = 0; plan->idist = 0; plan->backwards = backwards; plan->chain = NULL; struct iovec dims[N]; struct iovec hmdims[N]; assert(0 != flags); // the cufft interface is strange, but we do our best... unsigned int k = 0; unsigned int l = 0; for (unsigned int i = 0; i < N; i++) { if (1 == dimensions[i]) continue; if (MD_IS_SET(flags, i)) { dims[k].n = dimensions[i]; dims[k].is = istrides[i] / CFL_SIZE; dims[k].os = ostrides[i] / CFL_SIZE; k++; } else { hmdims[l].n = dimensions[i]; hmdims[l].is = istrides[i] / CFL_SIZE; hmdims[l].os = ostrides[i] / CFL_SIZE; l++; } } assert(k > 0); int cudims[k]; int cuiemb[k]; int cuoemb[k]; long batchdims[l]; long batchistr[l]; long batchostr[l]; int lis = dims[0].is; int los = dims[0].os; if (k > 3) goto errout; for (unsigned int i = 0; i < k; i++) { // assert(dims[i].is == lis); // assert(dims[i].os == los); cudims[k - 1 - i] = dims[i].n; cuiemb[k - 1 - i] = dims[i].n; cuoemb[k - 1 - i] = dims[i].n; lis = dims[i].n * dims[i].is; los = dims[i].n * dims[i].os; } for (unsigned int i = 0; i < l; i++) { batchdims[i] = hmdims[i].n; batchistr[i] = hmdims[i].is; batchostr[i] = hmdims[i].os; } int istride = dims[0].is; int ostride = dims[0].os; int idist = lis; int odist = los; int cubs = 1; // check that batch dimensions can be collapsed to one unsigned int bi = md_calc_blockdim(l, batchdims, batchistr, hmdims[0].is); unsigned int bo = md_calc_blockdim(l, batchdims, batchostr, hmdims[0].os); if (bi != bo) goto errout; if (bi > 0) { idist = hmdims[0].is; odist = hmdims[0].os; cubs = md_calc_size(bi, batchdims); } if (l != bi) { // check that batch dimensions can be collapsed to one if (l - bi != md_calc_blockdim(l - bi, batchdims + bi, batchistr + bi, hmdims[bi].is)) goto errout; if (l - bo != md_calc_blockdim(l - bo, batchdims + bo, batchostr + bo, hmdims[bo].os)) goto errout; plan->idist = hmdims[bi].is; plan->odist = hmdims[bo].os; plan->batch = md_calc_size(l - bi, batchdims + bi); } assert(k <= 3); int err; #pragma omp critical err = cufftPlanMany(&plan->cufft, k, cudims, cuiemb, istride, idist, cuoemb, ostride, odist, CUFFT_C2C, cubs); if (CUFFT_SUCCESS != err) goto errout; return PTR_PASS(plan); errout: PTR_FREE(plan); return NULL; } struct fft_cuda_plan_s* fft_cuda_plan(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], const long istrides[D], bool backwards) { struct fft_cuda_plan_s* plan = fft_cuda_plan0(D, dimensions, flags, ostrides, istrides, backwards); if (NULL != plan) return plan; int lsb = ffs(flags) - 1; if (flags & lsb) { // FIXME: this couldbe better... struct fft_cuda_plan_s* plan = fft_cuda_plan0(D, dimensions, lsb, ostrides, istrides, backwards); if (NULL == plan) return NULL; plan->chain = fft_cuda_plan(D, dimensions, MD_CLEAR(flags, lsb), ostrides, ostrides, backwards); if (NULL == plan->chain) { fft_cuda_free_plan(plan); return NULL; } return plan; } return NULL; } void fft_cuda_free_plan(struct fft_cuda_plan_s* cuplan) { if (NULL != cuplan->chain) fft_cuda_free_plan(cuplan->chain); cufftDestroy(cuplan->cufft); xfree(cuplan); } void fft_cuda_exec(struct fft_cuda_plan_s* cuplan, complex float* dst, const complex float* src) { assert(cuda_ondevice(src)); assert(cuda_ondevice(dst)); assert(NULL != cuplan); int err; for (int i = 0; i < cuplan->batch; i++) { if (CUFFT_SUCCESS != (err = cufftExecC2C(cuplan->cufft, (cufftComplex*)src + i * cuplan->idist, (cufftComplex*)dst + i * cuplan->odist, (!cuplan->backwards) ? CUFFT_FORWARD : CUFFT_INVERSE))) error("CUFFT: %d\n", err); } if (NULL != cuplan->chain) fft_cuda_exec(cuplan->chain, dst, dst); } #endif bart-0.5.00/src/num/fft-cuda.h000066400000000000000000000010601353046746100157620ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ struct fft_cuda_plan_s; extern struct fft_cuda_plan_s* fft_cuda_plan(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], const long istrides[D], _Bool dir); extern void fft_cuda_free_plan(struct fft_cuda_plan_s* cuplan); extern void fft_cuda_exec(struct fft_cuda_plan_s* cuplan, complex float* dst, const complex float* src); bart-0.5.00/src/num/fft.c000066400000000000000000000400401353046746100150440ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * Copyright 2018. Massachusetts Institute of Technology. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2011-2018 Martin Uecker * 2014 Frank Ong * 2018 Siddharth Iyer * * * FFT. It uses FFTW or CUFFT internally. * * * Gauss, Carl F. 1805. "Nachlass: Theoria Interpolationis Methodo Nova * Tractata." Werke 3, pp. 265-327, Königliche Gesellschaft der * Wissenschaften, Göttingen, 1866 */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/ops.h" #include "misc/misc.h" #include "misc/debug.h" #include "fft.h" #undef fft_plan_s #ifdef USE_CUDA #include "num/gpuops.h" #include "fft-cuda.h" #define LAZY_CUDA #endif void fftscale2(unsigned int N, const long dimensions[N], unsigned long flags, const long ostrides[N], complex float* dst, const long istrides[N], const complex float* src) { long fft_dims[N]; md_select_dims(N, flags, fft_dims, dimensions); float scale = 1. / sqrtf((float)md_calc_size(N, fft_dims)); md_zsmul2(N, dimensions, ostrides, dst, istrides, src, scale); } void fftscale(unsigned int N, const long dims[N], unsigned long flags, complex float* dst, const complex float* src) { long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); fftscale2(N, dims, flags, strs, dst, strs, src); } static double fftmod_phase(long length, int j) { long center1 = length / 2; double shift = (double)center1 / (double)length; return ((double)j - (double)center1 / 2.) * shift; } static void fftmod2_r(unsigned int N, const long dims[N], unsigned long flags, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* src, bool inv, double phase) { if (0 == flags) { md_zsmul2(N, dims, ostrs, dst, istrs, src, cexp(M_PI * 2.i * (inv ? -phase : phase))); return; } /* this will also currently be slow on the GPU because we do not * support strides there on the lowest level */ unsigned int i = N - 1; while (!MD_IS_SET(flags, i)) i--; #if 1 // If there is only one dimensions left and it is the innermost // which is contiguous optimize using md_zfftmod2 if ((0u == MD_CLEAR(flags, i)) && (1 == md_calc_size(i, dims)) && (CFL_SIZE == ostrs[i]) && (CFL_SIZE == istrs[i])) { md_zfftmod2(N - i, dims + i, ostrs + i, dst, istrs + i, src, inv, phase); return; } #endif long tdims[N]; md_select_dims(N, ~MD_BIT(i), tdims, dims); #pragma omp parallel for for (int j = 0; j < dims[i]; j++) fftmod2_r(N, tdims, MD_CLEAR(flags, i), ostrs, (void*)dst + j * ostrs[i], istrs, (void*)src + j * istrs[i], inv, phase + fftmod_phase(dims[i], j)); } static unsigned long clear_singletons(unsigned int N, const long dims[N], unsigned long flags) { return (0 == N) ? flags : clear_singletons(N - 1, dims, (1 == dims[N - 1]) ? MD_CLEAR(flags, N - 1) : flags); } void fftmod2(unsigned int N, const long dims[N], unsigned long flags, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* src) { fftmod2_r(N, dims, clear_singletons(N, dims, flags), ostrs, dst, istrs, src, false, 0.); } /* * The correct usage is fftmod before and after fft and * ifftmod before and after ifft (this is different from * how fftshift/ifftshift has to be used) */ void ifftmod2(unsigned int N, const long dims[N], unsigned long flags, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* src) { fftmod2_r(N, dims, clear_singletons(N, dims, flags), ostrs, dst, istrs, src, true, 0.); } void fftmod(unsigned int N, const long dimensions[N], unsigned long flags, complex float* dst, const complex float* src) { long strs[N]; md_calc_strides(N, strs, dimensions, CFL_SIZE); fftmod2(N, dimensions, flags, strs, dst, strs, src); } void ifftmod(unsigned int N, const long dimensions[N], unsigned long flags, complex float* dst, const complex float* src) { long strs[N]; md_calc_strides(N, strs, dimensions, CFL_SIZE); ifftmod2(N, dimensions, flags, strs, dst, strs, src); } void ifftshift2(unsigned int N, const long dims[N], unsigned long flags, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* src) { long pos[N]; md_set_dims(N, pos, 0); for (unsigned int i = 0; i < N; i++) if (MD_IS_SET(flags, i)) pos[i] = dims[i] - dims[i] / 2; md_circ_shift2(N, dims, pos, ostrs, dst, istrs, src, CFL_SIZE); } void ifftshift(unsigned int N, const long dimensions[N], unsigned long flags, complex float* dst, const complex float* src) { long strs[N]; md_calc_strides(N, strs, dimensions, CFL_SIZE); ifftshift2(N, dimensions, flags, strs, dst, strs, src); } void fftshift2(unsigned int N, const long dims[N], unsigned long flags, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* src) { long pos[N]; md_set_dims(N, pos, 0); for (unsigned int i = 0; i < N; i++) if (MD_IS_SET(flags, i)) pos[i] = dims[i] / 2; md_circ_shift2(N, dims, pos, ostrs, dst, istrs, src, CFL_SIZE); } void fftshift(unsigned int N, const long dimensions[N], unsigned long flags, complex float* dst, const complex float* src) { long strs[N]; md_calc_strides(N, strs, dimensions, CFL_SIZE); fftshift2(N, dimensions, flags, strs, dst, strs, src); } struct fft_plan_s { INTERFACE(operator_data_t); fftwf_plan fftw; #ifdef USE_CUDA #ifdef LAZY_CUDA unsigned int D; unsigned long flags; bool backwards; const long* dims; const long* istrs; const long* ostrs; #endif struct fft_cuda_plan_s* cuplan; #endif }; static DEF_TYPEID(fft_plan_s); static char* fftw_wisdom_name(unsigned int N, bool backwards, unsigned int flags, const long dims[N]) { char* tbpath = getenv("TOOLBOX_PATH"); if (NULL == tbpath) return NULL; char* loc = NULL; // Space for path and null terminator. size_t space = snprintf(loc, 0, "%s/save/fftw/N_%d_BACKWARD_%d_FLAGS_%d_DIMS", tbpath, N, backwards, flags); // Space for dimensions. for (size_t idx = 0; idx < N; idx ++) space += snprintf(loc, 0, "_%lu", dims[idx]); // Space for extension. space += snprintf(loc, 0, ".fftw"); // Space for null terminator. space += 1; loc = calloc(space, sizeof(char)); sprintf(loc , "%s/save/fftw/N_%d_BACKWARD_%d_FLAGS_%d_DIMS", tbpath, N, backwards, flags); char tmp[64]; for (size_t idx = 0; idx < N; idx++) { sprintf(tmp, "_%lu", dims[idx]); strcat(loc, tmp); } sprintf(tmp, ".fftw"); strcat(loc, tmp); loc[space - 1] = '\0'; return loc; } static fftwf_plan fft_fftwf_plan(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src, bool backwards, bool measure) { fftwf_plan fftwf; unsigned int N = D; fftwf_iodim64 dims[N]; fftwf_iodim64 hmdims[N]; unsigned int k = 0; unsigned int l = 0; char* wisdom = fftw_wisdom_name(D, backwards, flags, dimensions); if (NULL != wisdom) fftwf_import_wisdom_from_filename(wisdom); //FFTW seems to be fine with this //assert(0 != flags); for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { dims[k].n = dimensions[i]; dims[k].is = istrides[i] / CFL_SIZE; dims[k].os = ostrides[i] / CFL_SIZE; k++; } else { hmdims[l].n = dimensions[i]; hmdims[l].is = istrides[i] / CFL_SIZE; hmdims[l].os = ostrides[i] / CFL_SIZE; l++; } } #pragma omp critical fftwf = fftwf_plan_guru64_dft(k, dims, l, hmdims, (complex float*)src, dst, backwards ? 1 : (-1), measure ? FFTW_MEASURE : FFTW_ESTIMATE); if (NULL != wisdom) fftwf_export_wisdom_to_filename(wisdom); md_free(wisdom); return fftwf; } static void fft_apply(const operator_data_t* _plan, unsigned int N, void* args[N]) { complex float* dst = args[0]; const complex float* src = args[1]; const auto plan = CAST_DOWN(fft_plan_s, _plan); assert(2 == N); #ifdef USE_CUDA if (cuda_ondevice(src)) { #ifdef LAZY_CUDA if (NULL == plan->cuplan) ((struct fft_plan_s*)plan)->cuplan = fft_cuda_plan(plan->D, plan->dims, plan->flags, plan->ostrs, plan->istrs, plan->backwards); #endif assert(NULL != plan->cuplan); fft_cuda_exec(plan->cuplan, dst, src); } else #endif { assert(NULL != plan->fftw); fftwf_execute_dft(plan->fftw, (complex float*)src, dst); } } static void fft_free_plan(const operator_data_t* _data) { const auto plan = CAST_DOWN(fft_plan_s, _data); fftwf_destroy_plan(plan->fftw); #ifdef USE_CUDA #ifdef LAZY_CUDA xfree(plan->dims); xfree(plan->istrs); xfree(plan->ostrs); #endif if (NULL != plan->cuplan) fft_cuda_free_plan(plan->cuplan); #endif xfree(plan); } const struct operator_s* fft_measure_create(unsigned int D, const long dimensions[D], unsigned long flags, bool inplace, bool backwards) { PTR_ALLOC(struct fft_plan_s, plan); SET_TYPEID(fft_plan_s, plan); complex float* src = md_alloc(D, dimensions, CFL_SIZE); complex float* dst = inplace ? src : md_alloc(D, dimensions, CFL_SIZE); long strides[D]; md_calc_strides(D, strides, dimensions, CFL_SIZE); plan->fftw = fft_fftwf_plan(D, dimensions, flags, strides, dst, strides, src, backwards, true); md_free(src); if (!inplace) md_free(dst); #ifdef USE_CUDA plan->cuplan = NULL; #ifndef LAZY_CUDA if (cuda_ondevice(src)) plan->cuplan = fft_cuda_plan(D, dimensions, flags, strides, strides, backwards); #else plan->D = D; plan->flags = flags; plan->backwards = backwards; PTR_ALLOC(long[D], dims); md_copy_dims(D, *dims, dimensions); plan->dims = *PTR_PASS(dims); PTR_ALLOC(long[D], istrs); md_copy_strides(D, *istrs, strides); plan->istrs = *PTR_PASS(istrs); PTR_ALLOC(long[D], ostrs); md_copy_strides(D, *ostrs, strides); plan->ostrs = *PTR_PASS(ostrs); #endif #endif return operator_create2(D, dimensions, strides, D, dimensions, strides, CAST_UP(PTR_PASS(plan)), fft_apply, fft_free_plan); } const struct operator_s* fft_create2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src, bool backwards) { PTR_ALLOC(struct fft_plan_s, plan); SET_TYPEID(fft_plan_s, plan); plan->fftw = fft_fftwf_plan(D, dimensions, flags, ostrides, dst, istrides, src, backwards, false); #ifdef USE_CUDA plan->cuplan = NULL; #ifndef LAZY_CUDA if (cuda_ondevice(src)) plan->cuplan = fft_cuda_plan(D, dimensions, flags, ostrides, istrides, backwards); #else plan->D = D; plan->flags = flags; plan->backwards = backwards; PTR_ALLOC(long[D], dims); md_copy_dims(D, *dims, dimensions); plan->dims = *PTR_PASS(dims); PTR_ALLOC(long[D], istrs); md_copy_strides(D, *istrs, istrides); plan->istrs = *PTR_PASS(istrs); PTR_ALLOC(long[D], ostrs); md_copy_strides(D, *ostrs, ostrides); plan->ostrs = *PTR_PASS(ostrs); #endif #endif return operator_create2(D, dimensions, ostrides, D, dimensions, istrides, CAST_UP(PTR_PASS(plan)), fft_apply, fft_free_plan); } const struct operator_s* fft_create(unsigned int D, const long dimensions[D], unsigned long flags, complex float* dst, const complex float* src, bool backwards) { long strides[D]; md_calc_strides(D, strides, dimensions, CFL_SIZE); return fft_create2(D, dimensions, flags, strides, dst, strides, src, backwards); } void fft_exec(const struct operator_s* o, complex float* dst, const complex float* src) { operator_apply_unchecked(o, dst, src); } void fft_free(const struct operator_s* o) { operator_free(o); } void fft2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { const struct operator_s* plan = fft_create2(D, dimensions, flags, ostrides, dst, istrides, src, false); fft_exec(plan, dst, src); fft_free(plan); } void ifft2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { const struct operator_s* plan = fft_create2(D, dimensions, flags, ostrides, dst, istrides, src, true); fft_exec(plan, dst, src); fft_free(plan); } void fft(unsigned int D, const long dimensions[D], unsigned long flags, complex float* dst, const complex float* src) { const struct operator_s* plan = fft_create(D, dimensions, flags, dst, src, false); fft_exec(plan, dst, src); fft_free(plan); } void ifft(unsigned int D, const long dimensions[D], unsigned long flags, complex float* dst, const complex float* src) { const struct operator_s* plan = fft_create(D, dimensions, flags, dst, src, true); fft_exec(plan, dst, src); fft_free(plan); } void fftc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, complex float* dst, const complex float* src) { fftmod(D, dimensions, flags, dst, src); fft(D, dimensions, flags, dst, dst); fftmod(D, dimensions, flags, dst, dst); } void ifftc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, complex float* dst, const complex float* src) { ifftmod(D, dimensions, flags, dst, src); ifft(D, dimensions, flags, dst, dst); ifftmod(D, dimensions, flags, dst, dst); } void fftc2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { fftmod2(D, dimensions, flags, ostrides, dst, istrides, src); fft2(D, dimensions, flags, ostrides, dst, ostrides, dst); fftmod2(D, dimensions, flags, ostrides, dst, ostrides, dst); } void ifftc2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { ifftmod2(D, dimensions, flags, ostrides, dst, istrides, src); ifft2(D, dimensions, flags, ostrides, dst, ostrides, dst); ifftmod2(D, dimensions, flags, ostrides, dst, ostrides, dst); } void fftu(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, complex float* dst, const complex float* src) { fft(D, dimensions, flags, dst, src); fftscale(D, dimensions, flags, dst, dst); } void ifftu(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, complex float* dst, const complex float* src) { ifft(D, dimensions, flags, dst, src); fftscale(D, dimensions, flags, dst, dst); } void fftu2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { fft2(D, dimensions, flags, ostrides, dst, istrides, src); fftscale2(D, dimensions, flags, ostrides, dst, ostrides, dst); } void ifftu2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { ifft2(D, dimensions, flags, ostrides, dst, istrides, src); fftscale2(D, dimensions, flags, ostrides, dst, ostrides, dst); } void fftuc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, complex float* dst, const complex float* src) { fftc(D, dimensions, flags, dst, src); fftscale(D, dimensions, flags, dst, dst); } void ifftuc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, complex float* dst, const complex float* src) { ifftc(D, dimensions, flags, dst, src); fftscale(D, dimensions, flags, dst, dst); } void fftuc2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { fftc2(D, dimensions, flags, ostrides, dst, istrides, src); fftscale2(D, dimensions, flags, ostrides, dst, ostrides, dst); } void ifftuc2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { ifftc2(D, dimensions, flags, ostrides, dst, istrides, src); fftscale2(D, dimensions, flags, ostrides, dst, ostrides, dst); } bool fft_threads_init = false; void fft_set_num_threads(unsigned int n) { #ifdef FFTWTHREADS #pragma omp critical if (!fft_threads_init) { fft_threads_init = true; fftwf_init_threads(); } #pragma omp critical fftwf_plan_with_nthreads(n); #else UNUSED(n); #endif } bart-0.5.00/src/num/fft.h000066400000000000000000000132521353046746100150560ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2011, 2013 Martin Uecker */ #ifndef __FFT_H #define __FFT_H #include #include "misc/cppwrap.h" // similar to fftshift but modulates in the transform domain extern void fftmod(unsigned int N, const long dims[__VLA(N)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fftmod2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // fftmod for ifft extern void ifftmod(unsigned int N, const long dims[__VLA(N)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void ifftmod2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // apply scaling necessary for unitarity extern void fftscale(unsigned int N, const long dims[__VLA(N)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fftscale2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // fftshift extern void fftshift(unsigned int N, const long dims[__VLA(N)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fftshift2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // ifftshift extern void ifftshift(unsigned int N, const long dims[__VLA(N)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void ifftshift2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // FFT extern void fft(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void ifft(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fft2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); extern void ifft2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // centered extern void fftc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void ifftc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fftc2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); extern void ifftc2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // unitary extern void fftu(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void ifftu(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fftu2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); extern void ifftu2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); // unitary and centered extern void fftuc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void ifftuc(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src); extern void fftuc2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); extern void ifftuc2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src); struct operator_s; extern const struct operator_s* fft_create(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Complex float* dst, const _Complex float* src, _Bool backwards); extern const struct operator_s* fft_create2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long ostrides[__VLA(D)], _Complex float* dst, const long istrides[__VLA(D)], const _Complex float* src, _Bool backwards); extern const struct operator_s* fft_measure_create(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, _Bool inplace, _Bool backwards); // interface using a plan extern void fft_exec(const struct operator_s* plan, _Complex float* dst, const _Complex float* src); extern void fft_free(const struct operator_s* plan); extern void fft_set_num_threads(unsigned int n); #include "misc/cppwrap.h" #endif bart-0.5.00/src/num/filter.c000066400000000000000000000163151353046746100155620ustar00rootroot00000000000000/* Copyright 2015-2017. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2017 Martin Uecker * 2017 Jon Tamir */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/loop.h" #include "misc/misc.h" #include "misc/nested.h" #include "filter.h" static int cmp_float(const void* a, const void* b) { return (*(float*)a - *(float*)b > 0.) ? 1. : -1.; } static int cmp_complex_float(const void* a, const void* b) // gives sign for 0. (not 0) { return (cabsf(*(complex float*)a) - cabsf(*(complex float*)b) > 0.) ? 1. : -1.; } static void sort_floats(int N, float ar[N]) { qsort((void*)ar, N, sizeof(float), cmp_float); } static void sort_complex_floats(int N, complex float ar[N]) { qsort((void*)ar, N, sizeof(complex float), cmp_complex_float); } float median_float(int N, const float ar[N]) { float tmp[N]; memcpy(tmp, ar, N * sizeof(float)); sort_floats(N, tmp); return (1 == N % 2) ? tmp[(N - 1) / 2] : ((tmp[(N - 1) / 2 + 0] + tmp[(N - 1) / 2 + 1]) / 2.); } complex float median_complex_float(int N, const complex float ar[N]) { complex float tmp[N]; memcpy(tmp, ar, N * sizeof(complex float)); sort_complex_floats(N, tmp); return (1 == N % 2) ? tmp[(N - 1) / 2] : ((tmp[(N - 1) / 2 + 0] + tmp[(N - 1) / 2 + 1]) / 2.); } void md_medianz2(int D, int M, const long dim[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { assert(M < D); const long* nstr[2] = { ostr, istr }; void* nptr[2] = { optr, (void*)iptr }; long length = dim[M]; long stride = istr[M]; long dim2[D]; for (int i = 0; i < D; i++) dim2[i] = dim[i]; dim2[M] = 1; NESTED(void, nary_medianz, (void* ptr[])) { complex float tmp[length]; for (long i = 0; i < length; i++) tmp[i] = *((complex float*)(ptr[1] + i * stride)); *(complex float*)ptr[0] = median_complex_float(length, tmp); }; md_nary(2, D, dim2, nstr, nptr, nary_medianz); } void md_medianz(int D, int M, const long dim[D], complex float* optr, const complex float* iptr) { assert(M < D); long dim2[D]; for (int i = 0; i < D; i++) dim2[i] = dim[i]; dim2[M] = 1; long istr[D]; long ostr[D]; md_calc_strides(D, istr, dim, 8); md_calc_strides(D, ostr, dim2, 8); md_medianz2(D, M, dim, ostr, optr, istr, iptr); } void centered_gradient(unsigned int N, const long dims[N], const complex float grad[N], complex float* out) { md_zgradient(N, dims, out, grad); long dims0[N]; md_singleton_dims(N, dims0); long strs0[N]; md_calc_strides(N, strs0, dims0, CFL_SIZE); complex float cn = 0.; for (unsigned int n = 0; n < N; n++) cn -= grad[n] * (float)dims[n] / 2.; long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); md_zadd2(N, dims, strs, out, strs, out, strs0, &cn); } void linear_phase(unsigned int N, const long dims[N], const float pos[N], complex float* out) { complex float grad[N]; for (unsigned int n = 0; n < N; n++) grad[n] = 2.i * M_PI * (float)(pos[n]) / ((float)dims[n]); centered_gradient(N, dims, grad, out); md_zmap(N, dims, out, out, cexpf); } void klaplace_scaled(unsigned int N, const long dims[N], unsigned int flags, const float sc[N], complex float* out) { unsigned int flags2 = flags; complex float* tmp = md_alloc(N, dims, CFL_SIZE); md_clear(N, dims, out, CFL_SIZE); for (unsigned int i = 0; i < bitcount(flags); i++) { unsigned int lsb = ffs(flags2) - 1; flags2 = MD_CLEAR(flags2, lsb); complex float grad[N]; for (unsigned int j = 0; j < N; j++) grad[j] = 0.; grad[lsb] = sc[lsb]; centered_gradient(N, dims, grad, tmp); md_zspow(N, dims, tmp, tmp, 2.); md_zadd(N, dims, out, out, tmp); } md_free(tmp); } void klaplace(unsigned int N, const long dims[N], unsigned int flags, complex float* out) { float sc[N]; for (unsigned int j = 0; j < N; j++) sc[j] = 1. / (float)dims[j]; klaplace_scaled(N, dims, flags, sc, out); } static void nary_zwindow(const long N, const float alpha, const float beta, complex float* ptr) { if (1 == N) { ptr[0] = 1.; return; } #pragma omp parallel for for (long i = 0; i < N; i++) ptr[i] = alpha - beta * cosf(2. * M_PI * i / (N - 1)); } static void nary_zhamming(const long N, complex float* ptr) { #if 0 const float alpha = 0.53836; const float beta = 0.46164; #else const float alpha = 0.54; const float beta = 0.46; #endif return nary_zwindow(N, alpha, beta, ptr); } static void nary_zhann(const long N, complex float* ptr) { const float alpha = 0.5; const float beta = 0.5; return nary_zwindow(N, alpha, beta, ptr); } enum window_type { WINDOW_HAMMING, WINDOW_HANN }; static void md_zwindow2(unsigned int D, const long dims[D], unsigned int flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr, enum window_type wt) { if (0 == flags) { md_copy2(D, dims, ostrs, optr, istrs, iptr, CFL_SIZE); return; } // process first flagged dimension unsigned int lsb = ffs(flags) - 1; long win_dims[D]; long win_strs[D]; md_select_dims(D, MD_BIT(lsb), win_dims, dims); md_calc_strides(D, win_strs, win_dims, CFL_SIZE); complex float* win = md_alloc_sameplace(D, win_dims, CFL_SIZE, iptr); switch (wt) { case WINDOW_HAMMING: nary_zhamming(dims[lsb], win); break; case WINDOW_HANN: nary_zhann(dims[lsb], win); break; }; md_zmul2(D, dims, ostrs, optr, istrs, iptr, win_strs, win); md_free(win); flags = MD_CLEAR(flags, lsb); // process other dimensions if (0 != flags) md_zwindow2(D, dims, flags, ostrs, optr, ostrs, optr, wt); return; } #if 0 static void md_zwindow(const unsigned int D, const long dims[D], const long flags, complex float* optr, const complex float* iptr, bool hamming) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zwindow2(D, dims, flags, strs, optr, strs, iptr, hamming); } #endif /* * Apply Hamming window to iptr along flags */ void md_zhamming(const unsigned int D, const long dims[D], const long flags, complex float* optr, const complex float* iptr) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); return md_zhamming2(D, dims, flags, strs, optr, strs, iptr); } /* * Apply Hamming window to iptr along flags (with strides) */ void md_zhamming2(const unsigned int D, const long dims[D], const long flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { return md_zwindow2(D, dims, flags, ostrs, optr, istrs, iptr, WINDOW_HAMMING); } /* * Apply Hann window to iptr along flags */ void md_zhann(const unsigned int D, const long dims[D], const long flags, complex float* optr, const complex float* iptr) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); return md_zhann2(D, dims, flags, strs, optr, strs, iptr); } /* * Apply Hann window to iptr along flags (with strides) */ void md_zhann2(const unsigned int D, const long dims[D], const long flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { return md_zwindow2(D, dims, flags, ostrs, optr, istrs, iptr, WINDOW_HANN); } bart-0.5.00/src/num/filter.h000066400000000000000000000031001353046746100155530ustar00rootroot00000000000000 #include #include "misc/cppwrap.h" extern float median_float(int N, const float ar[N]); extern complex float median_complex_float(int N, const complex float ar[N]); extern void md_medianz2(int D, int M, const long dim[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr); extern void md_medianz(int D, int M, const long dim[D], complex float* optr, const complex float* iptr); extern void linear_phase(unsigned int N, const long dims[__VLA(N)], const float pos[__VLA(N)], _Complex float* out); extern void centered_gradient(unsigned int N, const long dims[__VLA(N)], const _Complex float grad[__VLA(N)], _Complex float* out); extern void klaplace(unsigned int N, const long dims[__VLA(N)], unsigned int flags, _Complex float* out); void klaplace_scaled(unsigned int N, const long dims[N], unsigned int flags, const float sc[N], complex float* out); extern void md_zhamming(const unsigned int D, const long dims[__VLA(D)], const long flags, complex float* optr, const complex float* iptr); extern void md_zhamming2(const unsigned int D, const long dims[__VLA(D)], const long flags, const long ostr[__VLA(D)], complex float* optr, const long istr[__VLA(D)], const complex float* iptr); extern void md_zhann(const unsigned int D, const long dims[__VLA(D)], const long flags, complex float* optr, const complex float* iptr); extern void md_zhann2(const unsigned int D, const long dims[__VLA(D)], const long flags, const long ostr[__VLA(D)], complex float* optr, const long istr[__VLA(D)], const complex float* iptr); #include "misc/cppwrap.h" bart-0.5.00/src/num/flpmath.c000066400000000000000000003105011353046746100157220ustar00rootroot00000000000000/* Copyright 2013-2018 The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * 2013 Dara Bahri * 2014 Frank Ong * 2014-2018 Jonathan Tamir * 2016 Siddharth Iyer * 2017 Sofia Dimoudi * * * Operations on arrays of complex single-precision floating * point numbers. Most functions come in two flavours: * * 1. A basic version which takes the number of dimensions, an array * of long integers specifing the size of each dimension, the pointers * to the data, and the size of each element and other required parameters. * * 2. An extended version which takes an array of long integers which * specifies the strides for each argument. * * All functions should work on CPU and GPU. * */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/vecops.h" #include "num/optimize.h" #include "num/blas.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/debug.h" #include "misc/nested.h" #ifdef USE_CUDA #include "num/gpuops.h" /* * including gpukrnls.h so that I can directly call cuda_zreal. * this can be removed after md_zreal is optimized for GPU. */ #include "num/gpukrnls.h" #endif typedef void (*md_2op_t)(unsigned int D, const long dims[D], const long ostrs[D], float* optr, const long istrs1[D], const float* iptr1); typedef void (*md_z2op_t)(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long istrs1[D], const complex float* iptr1); typedef void (*md_2opf_t)(unsigned int D, const long dims[D], const long ostrs[D], float* optr, const long istrs1[D], const double* iptr1); typedef void (*md_2opd_t)(unsigned int D, const long dims[D], const long ostrs[D], double* optr, const long istrs1[D], const float* iptr1); typedef void (*md_z2opf_t)(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long istrs1[D], const complex double* iptr1); typedef void (*md_z2opd_t)(unsigned int D, const long dims[D], const long ostrs[D], complex double* optr, const long istrs1[D], const complex float* iptr1); typedef void (*md_3op_t)(unsigned int D, const long dims[D], const long ostrs[D], float* optr, const long istrs1[D], const float* iptr1, const long istrs2[D], const float* iptr2); typedef void (*md_z3op_t)(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long istrs1[D], const complex float* iptr1, const long istrs2[D], const complex float* iptr2); typedef void (*md_3opd_t)(unsigned int D, const long dims[D], const long ostrs[D], double* optr, const long istrs1[D], const float* iptr1, const long istrs2[D], const float* iptr2); typedef void (*md_z3opd_t)(unsigned int D, const long dims[D], const long ostrs[D], complex double* optr, const long istrs1[D], const complex float* iptr1, const long istrs2[D], const complex float* iptr2); #if 0 static void optimized_twoop(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr1[D], void* iptr1, size_t sizes[2], md_nary_fun_t too, void* data_ptr) __attribute__((always_inline)); static void optimized_twoop_oi(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr1[D], const void* iptr1, size_t sizes[2], md_nary_fun_t too, void* data_ptr) __attribute__((always_inline)); static void optimized_threeop(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr1[D], void* iptr1, const long istr2[D], void* iptr2, size_t sizes[3], md_nary_fun_t too, void* data_ptr) __attribute__((always_inline)); static void optimized_threeop_oii(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr1[D], const void* iptr1, const long istr2[D], const void* iptr2, size_t sizes[3], md_nary_fun_t too, void* data_ptr) __attribute__((always_inline)); static void make_z3op_simple(md_z3op_t fun, unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) __attribute__((always_inline)); static void make_3op_simple(md_3op_t fun, unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) __attribute__((always_inline)); static void make_z3op(size_t offset, unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) __attribute__((always_inline)); static void make_3opd_simple(md_3opd_t fun, unsigned int D, const long dims[D], double* optr, const float* iptr1, const float* iptr2) __attribute__((always_inline)); static void make_z2op_simple(md_z2op_t fun, unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1) __attribute__((always_inline)); static void make_2op_simple(md_2op_t fun, unsigned int D, const long dims[D], float* optr, const float* iptr1) __attribute__((always_inline)); #endif /** * Optimized two-op wrapper. Use when input is constant * * @param D number of dimensions * @param dim dimensions * @param ostr output strides * @param optr output * @param istr1 input 1 strides * @param iptr1 input 1 (constant) * @param size size of data structures, e.g. complex float * @param too two-op multiply function */ static void optimized_twoop_oi(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr1[D], const void* iptr1, size_t sizes[2], md_nary_opt_fun_t too) { const long (*nstr[2])[D?D:1] = { (const long (*)[D?D:1])ostr, (const long (*)[D?D:1])istr1 }; void *nptr[2] = { optr, (void*)iptr1 }; unsigned int io = 1 + ((iptr1 == optr) ? 2 : 0); optimized_nop(2, io, D, dim, nstr, nptr, sizes, too); } /** * Optimized threeop wrapper. Use when inputs are constants * * @param D number of dimensions * @param dim dimensions * @param ostr output strides * @param optr output * @param istr1 input 1 strides * @param iptr1 input 1 (constant) * @param istr2 input 2 strides * @param iptr2 input 2 (constant) * @param size size of data structures, e.g. complex float * @param too three-op multiply function */ static void optimized_threeop_oii(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr1[D], const void* iptr1, const long istr2[D], const void* iptr2, size_t sizes[3], md_nary_opt_fun_t too) { const long (*nstr[3])[D?D:1] = { (const long (*)[D?D:1])ostr, (const long (*)[D?D:1])istr1, (const long (*)[D?D:1])istr2 }; void *nptr[3] = { optr, (void*)iptr1, (void*)iptr2 }; unsigned int io = 1 + ((iptr1 == optr) ? 2 : 0) + ((iptr2 == optr) ? 4 : 0); optimized_nop(3, io, D, dim, nstr, nptr, sizes, too); } /* HELPER FUNCTIONS * * The following functions, typedefs, and macros are used internally in flpmath.c * to simplify implementation of many similar functions. */ typedef void (*r2op_t)(long N, float* dst, const float* src1); typedef void (*z2op_t)(long N, complex float* dst, const complex float* src1); typedef void (*r3op_t)(long N, float* dst, const float* src1, const float* src2); typedef void (*z3op_t)(long N, complex float* dst, const complex float* src1, const complex float* src2); typedef void (*r2opd_t)(long N, double* dst, const float* src1); typedef void (*z2opd_t)(long N, complex double* dst, const complex float* src1); typedef void (*r3opd_t)(long N, double* dst, const float* src1, const float* src2); typedef void (*z3opd_t)(long N, complex double* dst, const complex float* src1, const complex float* src2); typedef void (*r2opf_t)(long N, float* dst, const double* src1); typedef void (*z2opf_t)(long N, complex float* dst, const complex double* src1); static void make_z3op_simple(md_z3op_t fun, unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); fun(D, dims, strs, optr, strs, iptr1, strs, iptr2); } static void make_3op_simple(md_3op_t fun, unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); fun(D, dims, strs, optr, strs, iptr1, strs, iptr2); } static void make_z3opd_simple(md_z3opd_t fun, unsigned int D, const long dims[D], complex double* optr, const complex float* iptr1, const complex float* iptr2) { long strs_single[D]; long strs_double[D]; md_calc_strides(D, strs_single, dims, CFL_SIZE); md_calc_strides(D, strs_double, dims, CDL_SIZE); fun(D, dims, strs_double, optr, strs_single, iptr1, strs_single, iptr2); } static void make_3opd_simple(md_3opd_t fun, unsigned int D, const long dims[D], double* optr, const float* iptr1, const float* iptr2) { long strs_single[D]; long strs_double[D]; md_calc_strides(D, strs_single, dims, FL_SIZE); md_calc_strides(D, strs_double, dims, DL_SIZE); fun(D, dims, strs_double, optr, strs_single, iptr1, strs_single, iptr2); } static void make_z2op_simple(md_z2op_t fun, unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); fun(D, dims, strs, optr, strs, iptr1); } static void make_2op_simple(md_2op_t fun, unsigned int D, const long dims[D], float* optr, const float* iptr1) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); fun(D, dims, strs, optr, strs, iptr1); } static void make_z2opd_simple(md_z2opd_t fun, unsigned int D, const long dims[D], complex double* optr, const complex float* iptr1) { long strs_single[D]; long strs_double[D]; md_calc_strides(D, strs_single, dims, CFL_SIZE); md_calc_strides(D, strs_double, dims, CDL_SIZE); fun(D, dims, strs_double, optr, strs_single, iptr1); } static void make_2opd_simple(md_2opd_t fun, unsigned int D, const long dims[D], double* optr, const float* iptr1) { long strs_single[D]; long strs_double[D]; md_calc_strides(D, strs_single, dims, FL_SIZE); md_calc_strides(D, strs_double, dims, DL_SIZE); fun(D, dims, strs_double, optr, strs_single, iptr1); } static void make_z3op(size_t offset, unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { NESTED(void, nary_z3op, (struct nary_opt_data_s* data, void* ptr[])) { (*(z3op_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1], ptr[2]); }; optimized_threeop_oii(D, dim, ostr, optr, istr1, iptr1, istr2, iptr2, (size_t[3]){ [0 ... 2] = CFL_SIZE }, nary_z3op); } static void make_3op(size_t offset, unsigned int D, const long dim[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { NESTED(void, nary_3op, (struct nary_opt_data_s* data, void* ptr[])) { (*(r3op_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1], ptr[2]); }; optimized_threeop_oii(D, dim, ostr, optr, istr1, iptr1, istr2, iptr2, (size_t[3]){ [0 ... 2] = FL_SIZE }, nary_3op); } static void make_z3opd(size_t offset, unsigned int D, const long dim[D], const long ostr[D], complex double* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { NESTED(void, nary_z3opd, (struct nary_opt_data_s* data, void* ptr[])) { (*(z3opd_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1], ptr[2]); }; optimized_threeop_oii(D, dim, ostr, optr, istr1, iptr1, istr2, iptr2, (size_t[3]){ CDL_SIZE, CFL_SIZE, CFL_SIZE }, nary_z3opd); } static void make_3opd(size_t offset, unsigned int D, const long dim[D], const long ostr[D], double* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { NESTED(void, nary_3opd, (struct nary_opt_data_s* data, void* ptr[])) { (*(r3opd_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1], ptr[2]); }; optimized_threeop_oii(D, dim, ostr, optr, istr1, iptr1, istr2, iptr2, (size_t[3]){ DL_SIZE, FL_SIZE, FL_SIZE }, nary_3opd); } static void make_z2op(size_t offset, unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1) { NESTED(void, nary_z2op, (struct nary_opt_data_s* data, void* ptr[])) { (*(z2op_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr1, iptr1, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_z2op); } static void make_2op(size_t offset, unsigned int D, const long dim[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1) { NESTED(void, nary_2op, (struct nary_opt_data_s* data, void* ptr[])) { (*(r2op_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr1, iptr1, (size_t[2]){ FL_SIZE, FL_SIZE }, nary_2op); } __attribute__((unused)) static void make_z2opd(size_t offset, unsigned int D, const long dim[D], const long ostr[D], complex double* optr, const long istr1[D], const complex float* iptr1) { size_t sizes[2] = { sizeof(complex double), sizeof(complex float) }; NESTED(void, nary_z2opd, (struct nary_opt_data_s* data, void* ptr[])) { (*(z2opd_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr1, iptr1, sizes, nary_z2opd); } static void make_2opd(size_t offset, unsigned int D, const long dim[D], const long ostr[D], double* optr, const long istr1[D], const float* iptr1) { NESTED(void, nary_2opd, (struct nary_opt_data_s* data, void* ptr[])) { (*(r2opd_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr1, iptr1, (size_t[2]){ DL_SIZE, FL_SIZE }, nary_2opd); } static void make_z2opf(size_t offset, unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex double* iptr1) { size_t sizes[2] = { sizeof(complex float), sizeof(complex double) }; NESTED(void, nary_z2opf, (struct nary_opt_data_s* data, void* ptr[])) { (*(z2opf_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr1, iptr1, sizes, nary_z2opf); } void* unused2 = make_z2opf; static void make_2opf(size_t offset, unsigned int D, const long dim[D], const long ostr[D], float* optr, const long istr1[D], const double* iptr1) { NESTED(void, nary_2opf, (struct nary_opt_data_s* data, void* ptr[])) { (*(r2opf_t*)(((char*)data->ops) + offset))(data->size, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr1, iptr1, (size_t[2]){ FL_SIZE, DL_SIZE }, nary_2opf); } static void make_z2opf_simple(md_z2opf_t fun, unsigned int D, const long dims[D], complex float* optr, const complex double* iptr1) { long strs_single[D]; long strs_double[D]; md_calc_strides(D, strs_single, dims, CFL_SIZE); md_calc_strides(D, strs_double, dims, CDL_SIZE); fun(D, dims, strs_single, optr, strs_double, iptr1); } static void make_2opf_simple(md_2opf_t fun, unsigned int D, const long dims[D], float* optr, const double* iptr1) { long strs_single[D]; long strs_double[D]; md_calc_strides(D, strs_single, dims, FL_SIZE); md_calc_strides(D, strs_double, dims, DL_SIZE); fun(D, dims, strs_single, optr, strs_double, iptr1); } #ifdef USE_CUDA static void* gpu_constant(const void* vp, size_t size) { return md_gpu_move(1, (long[1]){ 1 }, vp, size); } #endif static void make_z3op_scalar(md_z3op_t fun, unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr, complex float val) { complex float* valp = &val; #ifdef USE_CUDA if (cuda_ondevice(optr)) valp = gpu_constant(&val, CFL_SIZE); #endif long strs1[D]; md_singleton_strides(D, strs1); fun(D, dims, ostr, optr, istr, iptr, strs1, valp); #ifdef USE_CUDA if (cuda_ondevice(optr)) md_free(valp); #endif } static void make_3op_scalar(md_3op_t fun, unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float val) { float* valp = &val; #ifdef USE_CUDA if (cuda_ondevice(optr)) valp = gpu_constant(&val, FL_SIZE); #endif long strs1[D]; md_singleton_strides(D, strs1); fun(D, dims, ostr, optr, istr, iptr, strs1, valp); #ifdef USE_CUDA if (cuda_ondevice(optr)) md_free(valp); #endif } static void real_from_complex_dims(unsigned int D, long odims[D + 1], const long idims[D]) { odims[0] = 2; md_copy_dims(D, odims + 1, idims); } static void real_from_complex_strides(unsigned int D, long ostrs[D + 1], const long istrs[D]) { ostrs[0] = FL_SIZE; md_copy_dims(D, ostrs + 1, istrs); // works for strides too } static void make_z3op_from_real(size_t offset, unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { long rdims[D + 1]; long rostr[D + 1]; long ristr1[D + 1]; long ristr2[D + 1]; real_from_complex_dims(D, rdims, dims); real_from_complex_strides(D, rostr, ostr); real_from_complex_strides(D, ristr1, istr1); real_from_complex_strides(D, ristr2, istr2); make_3op(offset, D + 1, rdims, rostr, (float*)optr, ristr1, (const float*)iptr1, ristr2, (const float*)iptr2); } static void make_z2opd_from_real(size_t offset, unsigned int D, const long dims[D], const long ostr[D], complex double* optr, const long istr1[D], const complex float* iptr1) { long rdims[D + 1]; long rostr[D + 1]; long ristr1[D + 1]; real_from_complex_dims(D, rdims, dims); real_from_complex_strides(D, rostr, ostr); real_from_complex_strides(D, ristr1, istr1); make_2opd(offset, D + 1, rdims, rostr, (double*)optr, ristr1, (const float*)iptr1); } static void make_z2opf_from_real(size_t offset, unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex double* iptr1) { long rdims[D + 1]; long rostr[D + 1]; long ristr1[D + 1]; real_from_complex_dims(D, rdims, dims); real_from_complex_strides(D, rostr, ostr); real_from_complex_strides(D, ristr1, istr1); make_2opf(offset, D + 1, rdims, rostr, (float*)optr, ristr1, (const double*)iptr1); } // type safe #define MAKE_3OP(fun, ...) ((void)TYPE_CHECK(r3op_t, cpu_ops.fun), make_3op(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z3OP(fun, ...) ((void)TYPE_CHECK(z3op_t, cpu_ops.fun), make_z3op(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_2OP(fun, ...) ((void)TYPE_CHECK(r2op_t, cpu_ops.fun), make_2op(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z2OP(fun, ...) ((void)TYPE_CHECK(z2op_t, cpu_ops.fun), make_z2op(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_2OPD(fun, ...) ((void)TYPE_CHECK(r2opd_t, cpu_ops.fun), make_2opd(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z2OPD(fun, ...) ((void)TYPE_CHECK(z2opd_t, cpu_ops.fun), make_z2opd(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_2OPF(fun, ...) ((void)TYPE_CHECK(r2opf_t, cpu_ops.fun), make_2opf(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z2OPF(fun, ...) ((void)TYPE_CHECK(z2opf_t, cpu_ops.fun), make_z2opf(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_3OPD(fun, ...) ((void)TYPE_CHECK(r3opd_t, cpu_ops.fun), make_3opd(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z3OPD(fun, ...) ((void)TYPE_CHECK(z3opd_t, cpu_ops.fun), make_z3opd(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z3OP_FROM_REAL(fun, ...) \ ((void)TYPE_CHECK(r3op_t, cpu_ops.fun), make_z3op_from_real(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z2OPD_FROM_REAL(fun, ...) \ ((void)TYPE_CHECK(r2opd_t, cpu_ops.fun), make_z2opd_from_real(offsetof(struct vec_ops, fun), __VA_ARGS__)) #define MAKE_Z2OPF_FROM_REAL(fun, ...) \ ((void)TYPE_CHECK(r2opf_t, cpu_ops.fun), make_z2opf_from_real(offsetof(struct vec_ops, fun), __VA_ARGS__)) /* The section with exported functions starts here. */ /** * Multiply two complex arrays and save to output (with strides) * * optr = iptr1 * iptr2 */ void md_zmul2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zmul, D, dim, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply two complex arrays and save to output (without strides) * * optr = iptr1 * iptr2 */ void md_zmul(unsigned int D, const long dim[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zmul2, D, dim, optr, iptr1, iptr2); } /** * Multiply two scalar arrays and save to output (with strides) * * optr = iptr1 * iptr2 */ void md_mul2(unsigned int D, const long dim[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(mul, D, dim, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply two scalar arrays and save to output (without strides) * * optr = iptr1 * iptr2 */ void md_mul(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_mul2, D, dims, optr, iptr1, iptr2); } /** * Multiply real and imaginary parts of two complex arrays separately and save to output (with strides) * * real(optr) = real(iptr1) * real(iptr2) * * imag(optr) = imag(iptr1) * imag(iptr2) */ void md_zrmul2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP_FROM_REAL(mul, D, dim, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply real and imaginary parts of two complex arrays separately and save to output (without strides) * * real(optr) = real(iptr1) * real(iptr2) * * imag(optr) = imag(iptr1) * imag(iptr2) */ void md_zrmul(unsigned int D, const long dim[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zrmul2, D, dim, optr, iptr1, iptr2); } /** * Multiply complex array with a scalar and save to output (with strides) * * optr = iptr * val */ void md_zsmul2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr, complex float val) { if (0. == cimagf(val)) { // strength reduction: complex to real multiplication long dimsR[D + 1]; long ostrR[D + 1]; long istrR[D + 1]; real_from_complex_dims(D, dimsR, dims); real_from_complex_strides(D, ostrR, ostr); real_from_complex_strides(D, istrR, istr); md_smul2(D + 1, dimsR, ostrR, (float*)optr, istrR, (const float*)iptr, crealf(val)); return; } #if 0 make_z3op_scalar(md_zmul2, D, dims, ostr, optr, istr, iptr, val); #else // FIXME: we should rather optimize md_zmul2 for this case NESTED(void, nary_zsmul, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zsmul(data->size, val, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dims, ostr, optr, istr, iptr, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zsmul); #endif } /** * Multiply complex array with a scalar and save to output (without strides) * * optr = iptr * val */ void md_zsmul(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr, complex float var) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zsmul2(D, dims, strs, optr, strs, iptr, var); } /** * Multiply scalar array with a scalar and save to output (with strides) * * optr = iptr * var */ void md_smul2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float var) { #ifdef USE_CUDA if (cuda_ondevice(iptr)) { assert(cuda_ondevice(optr)); if (md_calc_blockdim(D, dims, ostr, FL_SIZE) != D) goto fallback; if (md_calc_blockdim(D, dims, istr, FL_SIZE) != D) goto fallback; if (iptr == optr) { gpu_ops.axpy(md_calc_size(D, dims), optr, var - 1., iptr); return; } // no strides needed because of checks above md_clear(D, dims, optr, FL_SIZE); // or call md_zaxpy gpu_ops.axpy(md_calc_size(D, dims), optr, var, iptr); return; } fallback: #endif #if 0 make_3op_scalar(md_mul2, D, dims, ostr, optr, istr, iptr, var); #else // FIXME: we should rather optimize md_mul2 for this case (void)0; NESTED(void, nary_smul, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->smul(data->size, var, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dims, ostr, optr, istr, iptr, (size_t[2]){ FL_SIZE, FL_SIZE }, nary_smul); #endif } /** * Multiply scalar array with a scalar and save to output (without strides) * * optr = iptr * var */ void md_smul(unsigned int D, const long dims[D], float* optr, const float* iptr, float var) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_smul2(D, dims, strs, optr, strs, iptr, var); } /** * Multiply the first complex array with the conjugate of the second complex array and save to output (with strides) * * optr = iptr1 * conj(iptr2) */ void md_zmulc2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zmulc, D, dim, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply the first complex array with the conjugate of the second complex array and save to output (without strides) * * optr = iptr1 * conj(iptr2) */ void md_zmulc(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zmulc2, D, dims, optr, iptr1, iptr2); } /** * Divide the first complex array by the second complex array and save to output (with strides) * * optr = iptr1 / iptr2 */ void md_zdiv2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zdiv, D, dim, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Divide the first complex array by the second complex array and save to output (without strides) * * optr = iptr1 / iptr2 */ void md_zdiv(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zdiv2, D, dims, optr, iptr1, iptr2); } /** * Divide the first scalar array by the second scalar array and save to output (with strides) * * optr = iptr1 / iptr2 */ void md_div2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(div, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Divide the first scalar array by the second scalar array and save to output (without strides) * * optr = iptr1 / iptr2 */ void md_div(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_div2, D, dims, optr, iptr1, iptr2); } /** * Take the first complex array to the power of the second complex array and save to output (with strides) * * optr = iptr1 ^ iptr2 */ void md_zpow2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { #ifdef USE_CUDA // FIXME: something is broken with the cuda implementation of zpow assert(!(cuda_ondevice(optr) || cuda_ondevice(iptr1) || cuda_ondevice(iptr2))); #endif MAKE_Z3OP(zpow, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Take the first complex array to the power of the second complex array and save to output (without strides) * * optr = iptr1 ^ iptr2 */ void md_zpow(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zpow2, D, dims, optr, iptr1, iptr2); } /** * Take the first scalar array to the power of the second scalar array and save to output (with strides) * * optr = iptr1 ^ iptr2 */ void md_pow2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(pow, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Take the first scalar array to the power of the second scalar array and save to output (without strides) * * optr = iptr1 ^ iptr2 */ void md_pow(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_pow2, D, dims, optr, iptr1, iptr2); } /** * Take square root of scalar array and save to output (with strides) * * optr = sqrt(iptr) */ void md_sqrt2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr) { MAKE_2OP(sqrt, D, dims, ostr, optr, istr, iptr); } /** * Take square root of scalar array and save to output (without strides) * * optr = sqrt(iptr) */ void md_sqrt(unsigned int D, const long dims[D], float* optr, const float* iptr) { make_2op_simple(md_sqrt2, D, dims, optr, iptr); } /** * Take square root of complex array and save to output (with strides) * * optr = sqrt(iptr) */ void md_zsqrt2(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { md_zspow2(D, dims, ostrs, optr, istrs, iptr, 0.5); } /** * Take square root of complex array and save to output (without strides) * * optr = sqrt(iptr) */ void md_zsqrt(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zsqrt2, D, dims, optr, iptr); } /** * Raise complex array to the power of a scalar and save to output (without strides) * * optr = pow(iptr, scalar) */ void md_zspow(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr, complex float val) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zspow2(D, dims, strs, optr, strs, iptr, val); } /** * Raise complex array to the power of a scalar and save to output (with strides) * * optr = pow(iptr, scalar) */ void md_zspow2(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr, complex float val) { make_z3op_scalar(md_zpow2, D, dims, ostrs, optr, istrs, iptr, val); } /** * Convert float array to double array * * dst = (double)src */ void md_float2double2(unsigned int D, const long dims[D], const long ostr[D], double* dst, const long istr[D], const float* src) { MAKE_2OPD(float2double, D, dims, ostr, dst, istr, src); } /** * Convert float array to double array * * dst = (double)src */ void md_float2double(unsigned int D, const long dims[D], double* dst, const float* src) { make_2opd_simple(md_float2double2, D, dims, dst, src); } /** * Convert double array to float array * * dst = (double)src */ void md_double2float2(unsigned int D, const long dims[D], const long ostr[D], float* dst, const long istr[D], const double* src) { MAKE_2OPF(double2float, D, dims, ostr, dst, istr, src); } /** * Convert double array to float array * * dst = (float)src */ void md_double2float(unsigned int D, const long dims[D], float* dst, const double* src) { make_2opf_simple(md_double2float2, D, dims, dst, src); } /** * Convert complex float array to complex double array * * dst = (complex double)src */ void md_zdouble2float2(unsigned int D, const long dims[D], const long ostr[D], complex float* dst, const long istr[D], const complex double* src) { MAKE_Z2OPF_FROM_REAL(double2float, D, dims, ostr, dst, istr, src); } /** * Convert complex float array to complex double array * * dst = (complex double)src */ void md_zdouble2float(unsigned int D, const long dims[D], complex float* dst, const complex double* src) { make_z2opf_simple(md_zdouble2float2, D, dims, dst, src); } /** * Convert complex double array to complex float array * * dst = (complex float)src */ void md_zfloat2double2(unsigned int D, const long dims[D], const long ostr[D], complex double* dst, const long istr[D], const complex float* src) { MAKE_Z2OPD_FROM_REAL(float2double, D, dims, ostr, dst, istr, src); } /** * Convert complex double array to complex float array * * dst = (complex float)src */ void md_zfloat2double(unsigned int D, const long dims[D], complex double* dst, const complex float* src) { make_z2opd_simple(md_zfloat2double2, D, dims, dst, src); } /* * A A A ok * A A 1 ok * A 1 A ok * 1 A A ok * A 1 1 ! * 1 A 1 ! * 1 1 A ! * 1 1 1 ok */ void md_tenmul_dims(unsigned int D, long max_dims[D], const long out_dims[D], const long in1_dims[D], const long in2_dims[D]) { md_max_dims(D, ~0lu, max_dims, in1_dims, out_dims); long max2_dims[D]; md_max_dims(D, ~0lu, max2_dims, in2_dims, out_dims); assert(md_check_compat(D, 0lu, max_dims, max2_dims)); } static bool detect_matrix(const long dims[3], const long ostrs[3], const long mstrs[3], const long istrs[3]) { return ( (0 == ostrs[1]) && (0 == mstrs[2]) && (0 == istrs[0]) && ((CFL_SIZE == ostrs[0]) && (ostrs[0] * dims[0] == ostrs[2])) && ((CFL_SIZE == mstrs[0]) && (mstrs[0] * dims[0] == mstrs[1])) && ((CFL_SIZE == istrs[1]) && (istrs[1] * dims[1] == istrs[2]))); } static bool simple_matmul(unsigned int N, const long max_dims[N], const long ostrs[N], complex float* out, const long mstrs[N], const complex float* mat, const long istrs[N], const complex float* in) { long dims[N]; md_copy_dims(N, dims, max_dims); long ostrs2[N]; md_copy_strides(N, ostrs2, ostrs); long mstrs2[N]; md_copy_strides(N, mstrs2, mstrs); long istrs2[N]; md_copy_strides(N, istrs2, istrs); long (*strs[3])[N] = { &ostrs2, &istrs2, &mstrs2 }; unsigned int ND = simplify_dims(3, N, dims, strs); if (ND < 3) return false; long C = dims[0]; long B = dims[1]; long A = dims[2]; if ((3 == ND) && detect_matrix(dims, ostrs2, istrs2, mstrs2)) { debug_printf(DP_DEBUG4, "matmul: matrix multiplication (1).\n"); #if 0 // num/linalg.h mat_mul(A, B, C, *(complex float (*)[A][C])out, *(const complex float (*)[A][B])mat, *(const complex float (*)[B][C])in); #else blas_matrix_multiply(C, A, B, *(complex float (*)[A][C])out, *(const complex float (*)[B][C])in, *(const complex float (*)[A][B])mat); #endif return true; } if ((3 == ND) && detect_matrix(dims, ostrs2, mstrs2, istrs2)) { debug_printf(DP_DEBUG4, "matmul: matrix multiplication (2).\n"); #if 0 // num/linalg.h mat_mul(A, B, C, *(complex float (*)[A][C])out, *(const complex float (*)[A][B])in, *(const complex float (*)[B][C])mat); #else blas_matrix_multiply(C, A, B, *(complex float (*)[A][C])out, *(const complex float (*)[B][C])mat, *(const complex float (*)[A][B])in); #endif return true; } return false; } /* * tenmul (tensor multiplication) family of functions are revised * versions of the matmul functions. */ void md_ztenmul2(unsigned int D, const long max_dims[D], const long out_strs[D], complex float* out, const long in1_strs[D], const complex float* in1, const long in2_strs[D], const complex float* in2) { if (simple_matmul(D, max_dims, out_strs, out, in2_strs, in2, in1_strs, in1)) return; md_clear2(D, max_dims, out_strs, out, CFL_SIZE); md_zfmac2(D, max_dims, out_strs, out, in1_strs, in1, in2_strs, in2); } void md_ztenmulc2(unsigned int D, const long max_dims[D], const long out_strs[D], complex float* out, const long in1_strs[D], const complex float* in1, const long in2_strs[D], const complex float* in2) { md_clear2(D, max_dims, out_strs, out, CFL_SIZE); md_zfmacc2(D, max_dims, out_strs, out, in1_strs, in1, in2_strs, in2); } void md_ztenmul(unsigned int D, const long out_dims[D], complex float* out, const long in1_dims[D], const complex float* in1, const long in2_dims[D], const complex float* in2) { long max_dims[D]; md_tenmul_dims(D, max_dims, out_dims, in1_dims, in2_dims); md_ztenmul2(D, max_dims, MD_STRIDES(D, out_dims, CFL_SIZE), out, MD_STRIDES(D, in1_dims, CFL_SIZE), in1, MD_STRIDES(D, in2_dims, CFL_SIZE), in2); } void md_ztenmulc(unsigned int D, const long out_dims[D], complex float* out, const long in1_dims[D], const complex float* in1, const long in2_dims[D], const complex float* in2) { long max_dims[D]; md_tenmul_dims(D, max_dims, out_dims, in1_dims, in2_dims); md_ztenmulc2(D, max_dims, MD_STRIDES(D, out_dims, CFL_SIZE), out, MD_STRIDES(D, in1_dims, CFL_SIZE), in1, MD_STRIDES(D, in2_dims, CFL_SIZE), in2); } static int calc_conv_geom(int N, unsigned long flags, long mdims[2 * N], long ostrs2[2 * N], long kstrs2[2 * N], long istrs2[2 * N], const long odims[N], const long ostrs[N], const long kdims[N], const long kstrs[N], const long idims[N], const long istrs[N]) { int shift = 0; md_copy_strides(N, ostrs2, ostrs); md_singleton_strides(N, ostrs2 + N); md_copy_strides(N, kstrs2, kstrs); md_singleton_strides(N, kstrs2 + N); md_copy_strides(N, istrs2, istrs); md_singleton_strides(N, istrs2 + N); md_copy_dims(N, mdims, odims); md_singleton_dims(N, mdims + N); for (int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { assert(odims[i] == idims[i] - kdims[i] + 1); mdims[0 + i] = odims[i]; mdims[N + i] = kdims[i]; kstrs2[0 + i] = 0; kstrs2[N + i] = -kstrs[i]; shift += (kdims[i] - 1) * kstrs[i]; istrs2[0 + i] = istrs[i]; istrs2[N + i] = istrs[i]; } else { assert((1 == odims[i]) || (odims[i] == idims[i]) || (odims[i] == kdims[i])); assert((1 == idims[i]) || (odims[i] == idims[i]) || (idims[i] == kdims[i])); assert((1 == kdims[i]) || (kdims[i] == idims[i]) || (odims[i] == kdims[i])); } } return shift; } void md_zconv2(int N, unsigned long flags, const long odims[N], const long ostrs[N], complex float* out, const long kdims[N], const long kstrs[N], const complex float* krn, const long idims[N], const long istrs[N], const complex float* in) { long mdims[2 * N]; long ostrs2[2 * N]; long kstrs2[2 * N]; long istrs2[2 * N]; krn += calc_conv_geom(N, flags, mdims, ostrs2, kstrs2, istrs2, odims, ostrs, kdims, kstrs, idims, istrs) / CFL_SIZE; md_ztenmul2(2 * N, mdims, ostrs2, out, kstrs2, krn, istrs2, in); } void md_zconv(int N, unsigned long flags, const long odims[N], complex float* out, const long kdims[N], const complex float* krn, const long idims[N], const complex float* in) { long ostrs[N]; md_calc_strides(N, ostrs, odims, CFL_SIZE); long kstrs[N]; md_calc_strides(N, kstrs, kdims, CFL_SIZE); long istrs[N]; md_calc_strides(N, istrs, idims, CFL_SIZE); md_zconv2(N, flags, odims, ostrs, out, kdims, kstrs, krn, idims, istrs, in); } /* * matmul family of functions is deprecated - use tenmul instead */ static void md_zmatmul2_priv(unsigned int D, const long out_dims[D], const long out_strs[D], complex float* dst, const long mat_dims[D], const long mat_strs[D], const complex float* mat, const long in_dims[D], const long in_strs[D], const complex float* src, bool conj) { long max_dims[D]; md_tenmul_dims(D, max_dims, out_dims, mat_dims, in_dims); if ((!conj) && simple_matmul(D, max_dims, out_strs, dst, mat_strs, mat, in_strs, src)) return; md_clear2(D, out_dims, out_strs, dst, CFL_SIZE); (conj ? md_zfmacc2 : md_zfmac2)(D, max_dims, out_strs, dst, in_strs, src, mat_strs, mat); } /** * Matrix conjugate multiplication (with strides) * FIXME simplify interface? use macros? */ void md_zmatmulc2(unsigned int D, const long out_dims[D], const long out_strs[D], complex float* dst, const long mat_dims[D], const long mat_strs[D], const complex float* mat, const long in_dims[D], const long in_strs[D], const complex float* src) { md_zmatmul2_priv(D, out_dims, out_strs, dst, mat_dims, mat_strs, mat, in_dims, in_strs, src, true); } /** * Matrix conjugate multiplication (without strides) */ void md_zmatmulc(unsigned int D, const long out_dims[D], complex float* dst, const long mat_dims[D], const complex float* mat, const long in_dims[D], const complex float* src) { md_zmatmulc2(D, out_dims, MD_STRIDES(D, out_dims, CFL_SIZE), dst, mat_dims, MD_STRIDES(D, mat_dims, CFL_SIZE), mat, in_dims, MD_STRIDES(D, in_dims, CFL_SIZE), src); } /** * Matrix multiplication (with strides) * FIXME simplify interface? * FIXME: implementation assumes strides == 0 for dims == 1 */ void md_zmatmul2(unsigned int D, const long out_dims[D], const long out_strs[D], complex float* dst, const long mat_dims[D], const long mat_strs[D], const complex float* mat, const long in_dims[D], const long in_strs[D], const complex float* src) { md_zmatmul2_priv(D, out_dims, out_strs, dst, mat_dims, mat_strs, mat, in_dims, in_strs, src, false); } /** * Matrix multiplication (without strides) */ void md_zmatmul(unsigned int D, const long out_dims[D], complex float* dst, const long mat_dims[D], const complex float* mat, const long in_dims[D], const complex float* src) { md_zmatmul2(D, out_dims, MD_STRIDES(D, out_dims, CFL_SIZE), dst, mat_dims, MD_STRIDES(D, mat_dims, CFL_SIZE), mat, in_dims, MD_STRIDES(D, in_dims, CFL_SIZE), src); } /** * Multiply two complex arrays and add to output (with strides) * * optr = optr + iptr1 * iptr2 */ void md_zfmac2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zfmac, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply two complex arrays and add to output (without strides) * * optr = optr + iptr1 * iptr2 */ void md_zfmac(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zfmac2, D, dims, optr, iptr1, iptr2); } /** * Multiply two complex arrays and add to output (with strides) * * optr = optr + iptr1 * iptr2 */ void md_zfmacD2(unsigned int D, const long dims[D], const long ostr[D], complex double* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OPD(zfmac2, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply two complex arrays and add to output (without strides) * * optr = optr + iptr1 * iptr2 */ void md_zfmacD(unsigned int D, const long dims[D], complex double* optr, const complex float* iptr1, const complex float* iptr2) { make_z3opd_simple(md_zfmacD2, D, dims, optr, iptr1, iptr2); } /** * Multiply two scalar arrays and add to output (with strides) * * optr = optr + iptr1 * iptr2 */ void md_fmac2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(fmac, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply two scalar arrays and add to output (without strides) * * optr = optr + iptr1 * iptr2 */ void md_fmac(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_fmac2, D, dims, optr, iptr1, iptr2); } /** * Multiply two scalar arrays and add to output (with strides) * * optr = optr + iptr1 * iptr2 */ void md_fmacD2(unsigned int D, const long dims[D], const long ostr[D], double* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OPD(fmac2, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply two scalar arrays and add to output (without strides) * * optr = optr + iptr1 * iptr2 */ void md_fmacD(unsigned int D, const long dims[D], double* optr, const float* iptr1, const float* iptr2) { make_3opd_simple(md_fmacD2, D, dims, optr, iptr1, iptr2); } /** * Multiply the first complex array with the conjugate of the second complex array and add to output (with strides) * * optr = optr + iptr1 * conj(iptr2) */ void md_zfmacc2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zfmacc, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply the first complex array with the conjugate of the second complex array and add to output (without strides) * * optr = optr + iptr1 * conj(iptr2) */ void md_zfmacc(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zfmacc2, D, dims, optr, iptr1, iptr2); } /** * Multiply the first complex array with the conjugate of the second complex array and add to output (with strides) * * optr = optr + iptr1 * conj(iptr2) */ void md_zfmaccD2(unsigned int D, const long dims[D], const long ostr[D], complex double* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OPD(zfmacc2, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply the first complex array with the conjugate of the second complex array and add to output (without strides) * * optr = optr + iptr1 * conj(iptr2) */ void md_zfmaccD(unsigned int D, const long dims[D], complex double* optr, const complex float* iptr1, const complex float* iptr2) { make_z3opd_simple(md_zfmaccD2, D, dims, optr, iptr1, iptr2); } /** * Multiply complex array with a scalar and add to output (with strides) * * optr = optr + iptr * val */ void md_zaxpy2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, complex float val, const long istr[D], const complex float* iptr) { #ifdef USE_CUDA // FIXME: faster on GPU complex float* tmp = md_alloc_sameplace(D, dims, CFL_SIZE, optr); md_zsmul2(D, dims, MD_STRIDES(D, dims, CFL_SIZE), tmp, istr, iptr, val); md_zadd2(D, dims, ostr, optr, ostr, optr, MD_STRIDES(D, dims, CFL_SIZE), tmp); md_free(tmp); return; #endif if (0. == cimagf(val)) { // strength reduction: complex to real multiplication long dimsR[D + 1]; long ostrR[D + 1]; long istrR[D + 1]; real_from_complex_dims(D, dimsR, dims); real_from_complex_strides(D, ostrR, ostr); real_from_complex_strides(D, istrR, istr); md_axpy2(D + 1, dimsR, ostrR, (float*)optr, crealf(val), istrR, (const float*)iptr); return; } make_z3op_scalar(md_zfmac2, D, dims, ostr, optr, istr, iptr, val); } /** * Max of inputs (without strides) * * optr = max(iptr1, iptr2) */ void md_max(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_max2(D, dims, strs, optr, strs, iptr1, strs, iptr2); } /** * Max of inputs (with strides) * * optr = max(iptr1, iptr2) */ void md_max2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(max, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Min of inputs (without strides) * * optr = min(iptr1, iptr2) */ void md_min(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_min2(D, dims, strs, optr, strs, iptr1, strs, iptr2); } /** * Min of inputs (with strides) * * optr = min(iptr1, iptr2) */ void md_min2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(min, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Max of inputs (without strides) * * optr = max(iptr1, iptr2) */ void md_zmax(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zmax2(D, dims, strs, optr, strs, iptr1, strs, iptr2); } /** * Max of inputs (with strides) * * optr = max(iptr1, iptr2) */ void md_zmax2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zmax, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Multiply complex array with a scalar and add to output (without strides) * * optr = optr + iptr * val */ void md_zaxpy(unsigned int D, const long dims[D], complex float* optr, complex float val, const complex float* iptr) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zaxpy2(D, dims, strs, optr, val, strs, iptr); } /** * Multiply scalar array with a scalar and add to output (with strides) * * optr = optr + iptr * val */ void md_axpy2(unsigned int D, const long dims[D], const long ostr[D], float* optr, float val, const long istr[D], const float* iptr) { if (0. == val) return; // strength reduction if (1. == val) { md_add2(D, dims, ostr, optr, ostr, optr, istr, iptr); return; } #ifdef USE_CUDA if (cuda_ondevice(iptr)) { assert(cuda_ondevice(optr)); if (md_calc_blockdim(D, dims, ostr, FL_SIZE) != D) goto fallback; if (md_calc_blockdim(D, dims, istr, FL_SIZE) != D) goto fallback; // (iptr == optr) is safe. gpu_ops.axpy(md_calc_size(D, dims), optr, val, iptr); return; } fallback: #endif make_3op_scalar(md_fmac2, D, dims, ostr, optr, istr, iptr, val); } /** * Multiply scalar array with a scalar and add to output (without strides) * * optr = optr + iptr * val */ void md_axpy(unsigned int D, const long dims[D], float* optr, float val, const float* iptr) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_axpy2(D, dims, strs, optr, val, strs, iptr); } /** * Add two complex arrays and save to output (with strides) * * optr = iptr1 + iptr2 */ void md_zadd2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP_FROM_REAL(add, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Add two complex arrays and save to output (without strides) * * optr = iptr1 + iptr2 */ void md_zadd(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zadd2, D, dims, optr, iptr1, iptr2); } /** * Add scalar to complex array (with strides) * * optr = iptr + val */ void md_zsadd2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr, complex float val) { make_z3op_scalar(md_zadd2, D, dims, ostr, optr, istr, iptr, val); } /** * Add scalar to complex array (without strides) * * optr = iptr + val */ void md_zsadd(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr, complex float val) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zsadd2(D, dims, strs, optr, strs, iptr, val); } /** * Subtract the first complex array from the second complex array and save to output (with strides) * * optr = iptr1 - iptr2 */ void md_zsub2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP_FROM_REAL(sub, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Subtract the first complex array from the second complex array and save to output (without strides) * * optr = iptr1 - iptr2 */ void md_zsub(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zsub2, D, dims, optr, iptr1, iptr2); } /** * Add two scalar arrays and save to output (with strides) * * optr = iptr1 + iptr2 */ void md_add2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(add, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Add two scalar arrays and save to output (without strides) * * optr = iptr1 + iptr2 */ void md_add(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_add2, D, dims, optr, iptr1, iptr2); } /** * Add scalar to scalar array (with strides) * * optr = iptr + val */ void md_sadd2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float val) { make_3op_scalar(md_add2, D, dims, ostr, optr, istr, iptr, val); } /** * Add scalar to scalar array (without strides) * * optr = iptr + val */ void md_sadd(unsigned int D, const long dims[D], float* optr, const float* iptr, float val) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_sadd2(D, dims, strs, optr, strs, iptr, val); } /** * Subtract the first scalar array from the second scalar array and save to output (with strides) * * optr = iptr1 - iptr2 */ void md_sub2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(sub, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Subtract the first scalar array from the second scalar array and save to output (without strides) * * optr = iptr1 - iptr2 */ void md_sub(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_sub2, D, dims, optr, iptr1, iptr2); } /** * Take complex conjugate of complex array and save to output (with strides) * * optr = conj(iptr) */ void md_zconj2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { MAKE_Z2OP(zconj, D, dims, ostr, optr, istr, iptr); } /** * Take complex conjugate of complex array and save to output (without strides) * * optr = conj(iptr) */ void md_zconj(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zconj2, D, dims, optr, iptr); } /** * Take the real part of complex array and save to output (with strides) * * optr = real(iptr) */ void md_zreal2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { make_z3op_scalar(md_zrmul2, D, dim, ostr, optr, istr, iptr, 1.); } /** * Take the real part of complex array and save to output (without strides) * * optr = real(iptr) */ void md_zreal(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { #ifdef USE_CUDA if (cuda_ondevice(iptr)) { assert(cuda_ondevice(optr)); cuda_zreal(md_calc_size(D, dims), optr, iptr); return; } #endif make_z2op_simple(md_zreal2, D, dims, optr, iptr); } /** * Take the imaginary part of complex array and save to output (with strides) * * optr = imag(iptr) */ void md_zimag2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { make_z3op_scalar(md_zrmul2, D, dim, ostr, optr, istr, iptr, 1.i); } /** * Take the imaginary part of complex array and save to output (without strides) * * optr = imag(iptr) */ void md_zimag(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zimag2, D, dims, optr, iptr); } /** * Compare two complex arrays (with strides) * * optr = iptr1 == iptr2 */ void md_zcmp2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zcmp, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Compare two complex arrays (without strides) * * optr = iptr1 == iptr2 */ void md_zcmp(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zcmp2, D, dims, optr, iptr1, iptr2); } /** * Elementwise less than or equal to (with strides) * * optr = (iptr1 <= iptr2) */ void md_zlessequal2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { MAKE_Z3OP(zle, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Elementwise less than or equal to (without strides) * * optr = (iptr1 <= iptr2) */ void md_zlessequal(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zlessequal2, D, dims, optr, iptr1, iptr2); } /** * Elementwise less than or equal to (with strides) * * optr = (iptr1 <= iptr2) */ void md_lessequal2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { MAKE_3OP(le, D, dims, ostr, optr, istr1, iptr1, istr2, iptr2); } /** * Elementwise less than or equal to (without strides) * * optr = (iptr1 <= iptr2) */ void md_lessequal(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_lessequal2, D, dims, optr, iptr1, iptr2); } /** * Elementwise less than or equal to scalar (with strides) * * optr = (iptr <= val) */ void md_slessequal2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float val) { make_3op_scalar(md_lessequal2, D, dims, ostr, optr, istr, iptr, val); } /** * Elementwise less than or equal to scalar (without strides) * * optr = (iptr <= val) */ void md_slessequal(unsigned int D, const long dims[D], float* optr, const float* iptr, float val) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_slessequal2(D, dims, strs, optr, strs, iptr, val); } /** * Elementwise greater than or equal to (with strides) * * optr = (iptr1 => iptr2) */ void md_zgreatequal2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr1[D], const complex float* iptr1, const long istr2[D], const complex float* iptr2) { md_zlessequal2(D, dims, ostr, optr, istr2, iptr2, istr1, iptr1); } /** * Elementwise greater than or equal to (without strides) * * optr = (iptr1 >= iptr2) */ void md_zgreatequal(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr1, const complex float* iptr2) { make_z3op_simple(md_zgreatequal2, D, dims, optr, iptr1, iptr2); } /** * Elementwise greater than or equal to (with strides) * * optr = (iptr1 => iptr2) */ void md_greatequal2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr1[D], const float* iptr1, const long istr2[D], const float* iptr2) { md_lessequal2(D, dims, ostr, optr, istr2, iptr2, istr1, iptr1); } /** * Elementwise greater than or equal to (without strides) * * optr = (iptr1 >= iptr2) */ void md_greatequal(unsigned int D, const long dims[D], float* optr, const float* iptr1, const float* iptr2) { make_3op_simple(md_greatequal2, D, dims, optr, iptr1, iptr2); } /** * Elementwise greater than or equal to scalar (with strides) * * optr = (iptr >= val) */ void md_sgreatequal2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float val) { make_3op_scalar(md_greatequal2, D, dims, ostr, optr, istr, iptr, val); } /** * Elementwise greater than or equal to scalar (without strides) * * optr = (iptr >= val) */ void md_sgreatequal(unsigned int D, const long dims[D], float* optr, const float* iptr, float val) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_sgreatequal2(D, dims, strs, optr, strs, iptr, val); } /** * Elementwise greater than or equal to scalar (with strides) * * optr = (iptr >= val) */ void md_zsgreatequal2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr, float val) { make_z3op_scalar(md_zgreatequal2, D, dims, ostr, optr, istr, iptr, val); } /** * Elementwise greater than or equal to scalar (without strides) * * optr = (iptr >= val) */ void md_zsgreatequal(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr, float val) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zsgreatequal2(D, dims, strs, optr, strs, iptr, val); } /** * Extract unit-norm complex exponentials from complex arrays (with strides) * * optr = iptr / abs(iptr) */ void md_zphsr2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { MAKE_Z2OP(zphsr, D, dims, ostr, optr, istr, iptr); } /** * Extract unit-norm complex exponentials from complex arrays (without strides) * * optr = iptr / abs(iptr) */ void md_zphsr(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zphsr2, D, dims, optr, iptr); } /** * Get complex exponential with phase = complex arrays (with strides) * * optr = zexp(j * iptr) */ void md_zexpj2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { MAKE_Z2OP(zexpj, D, dims, ostr, optr, istr, iptr); } /** * Get complex exponential with phase = complex arrays (without strides) * * optr = zexp(j * iptr) */ void md_zexpj(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zexpj2, D, dims, optr, iptr); } /** * Complex exponential * * optr = zexp(iptr) */ void md_zexp2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { MAKE_Z2OP(zexp, D, dims, ostr, optr, istr, iptr); } /** * Complex exponential * * optr = zexp(iptr) */ void md_zexp(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zexp2, D, dims, optr, iptr); } /** * Get argument of complex arrays (with strides) * * optr = zarg(iptr) */ void md_zarg2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { MAKE_Z2OP(zarg, D, dims, ostr, optr, istr, iptr); } /** * Get argument of complex arrays (without strides) * * optr = zarg(iptr) */ void md_zarg(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zarg2, D, dims, optr, iptr); } /** * Calculate inner product between two scalar arrays (with strides) * * return iptr1^T * iptr2 */ float md_scalar2(unsigned int D, const long dim[D], const long str1[D], const float* ptr1, const long str2[D], const float* ptr2) { #if 1 if ( (D == md_calc_blockdim(D, dim, str1, FL_SIZE)) && (D == md_calc_blockdim(D, dim, str2, FL_SIZE))) { #ifdef USE_CUDA if (cuda_ondevice(ptr1)) { assert(cuda_ondevice(ptr2)); return gpu_ops.dot(md_calc_size(D, dim), ptr1, ptr2); } #endif return cpu_ops.dot(md_calc_size(D, dim), ptr1, ptr2); } #endif double ret = 0.; double* retp = &ret; #ifdef USE_CUDA if (cuda_ondevice(ptr1)) retp = gpu_constant(&ret, DL_SIZE); #endif long stro[D]; md_singleton_strides(D, stro); // Because this might lose precision for large data sets // we use double precision to accumlate result // (Kahan summation formula would be another option) md_fmacD2(D, dim, stro, retp, str1, ptr1, str2, ptr2); #ifdef USE_CUDA if (cuda_ondevice(ptr1)) { md_copy(1, (long[1]){ 1 }, &ret, retp, DL_SIZE); md_free(retp); } #endif return ret; } /** * Calculate inner product between two scalar arrays (without strides) * * return iptr1^T * iptr2 */ float md_scalar(unsigned int D, const long dim[D], const float* ptr1, const float* ptr2) { long str[D]; md_calc_strides(D, str, dim, FL_SIZE); return md_scalar2(D, dim, str, ptr1, str, ptr2); } /** * Calculate l2 norm of scalar array (with strides) * * return sqrt(iptr^T * iptr) */ float md_norm2(unsigned int D, const long dim[D], const long str[D], const float* ptr) { return sqrtf(md_scalar2(D, dim, str, ptr, str, ptr)); } /** * Calculate l2 norm of scalar array (without strides) * * return sqrt(iptr^T * iptr) */ float md_norm(unsigned int D, const long dim[D], const float* ptr) { return sqrtf(md_scalar(D, dim, ptr, ptr)); } /** * Calculate root-mean-square of complex array * * return sqrt(in^H * in / length(in)) */ float md_zrms(unsigned int D, const long dim[D], const complex float* in) { return md_znorm(D, dim, in) / sqrtl(md_calc_size(D, dim)); } /** * Calculate root-mean-square error between two complex arrays * * return sqrt((in1 - in2)^2 / length(in)) */ float md_zrmse(unsigned int D, const long dim[D], const complex float* in1, const complex float* in2) { complex float* err = md_alloc_sameplace(D, dim, CFL_SIZE, in1); md_zsub(D, dim, err, in1, in2); float val = md_zrms(D, dim, err); md_free(err); return val; } /** * Calculate normalized root-mean-square error between two complex arrays * * return RMSE(ref,in) / RMS(in) */ float md_znrmse(unsigned int D, const long dim[D], const complex float* ref, const complex float* in) { return md_zrmse(D, dim, ref, in) / md_zrms(D, dim, ref); } /** * Calculate l2 norm error between two complex arrays * * return sqrt(sum(in1 - in2)^2) */ float md_znorme(unsigned int D, const long dim[D], const complex float* in1, const complex float* in2) { complex float* err = md_alloc_sameplace(D, dim, CFL_SIZE, in1); md_zsub(D, dim, err, in1, in2); float val = md_znorm(D, dim, err); md_free(err); return val; } /** * Calculate relative l2 norm error of two complex arrays * * return norm(ref - in) / norm(ref) */ float md_zrnorme(unsigned int D, const long dim[D], const complex float* ref, const complex float* in) { return md_znorme(D, dim, ref, in) / md_znorm(D, dim, ref); } /** * Calculate inner product between two complex arrays (with strides) * * return iptr1^H * iptr2 */ complex float md_zscalar2(unsigned int D, const long dim[D], const long str1[D], const complex float* ptr1, const long str2[D], const complex float* ptr2) { complex double ret = 0.; complex double* retp = &ret; #ifdef USE_CUDA if (cuda_ondevice(ptr1)) { // FIXME: because md_zfmacc2 with stride = 0 is slow complex float* tmp = md_alloc_gpu(D, dim, CFL_SIZE); long strs[D]; md_calc_strides(D, strs, dim, CFL_SIZE); md_clear(D, dim, tmp, CFL_SIZE); md_zfmacc2(D, dim, strs, tmp, str1, ptr1, str2, ptr2); gpu_ops.zsum(md_calc_size(D, dim), tmp); complex float ret = 0.; md_copy(1, (long[1]){ 1 }, &ret, tmp, CFL_SIZE); md_free(tmp); return ret; } #endif #ifdef USE_CUDA if (cuda_ondevice(ptr1)) retp = gpu_constant(&ret, CDL_SIZE); #endif long stro[D]; md_singleton_strides(D, stro); // Because this might lose precision for large data sets // we use double precision to accumlate result // (Kahan summation formula would be another option) md_zfmaccD2(D, dim, stro, retp, str1, ptr1, str2, ptr2); #ifdef USE_CUDA if (cuda_ondevice(ptr1)) { md_copy(1, (long[1]){ 1 }, &ret, retp, CDL_SIZE); md_free(retp); } #endif return (complex float)ret; } /** * Calculate inner product between two complex arrays (without strides) * * return iptr1^H * iptr2 */ complex float md_zscalar(unsigned int D, const long dim[D], const complex float* ptr1, const complex float* ptr2) { long str[D]; md_calc_strides(D, str, dim, CFL_SIZE); return md_zscalar2(D, dim, str, ptr1, str, ptr2); } /** * Calculate real part of the inner product between two complex arrays (with strides) * * return iptr1^H * iptr2 */ float md_zscalar_real2(unsigned int D, const long dims[D], const long strs1[D], const complex float* ptr1, const long strs2[D], const complex float* ptr2) { long dimsR[D + 1]; long strs1R[D + 1]; long strs2R[D + 1]; real_from_complex_dims(D, dimsR, dims); real_from_complex_strides(D, strs1R, strs1); real_from_complex_strides(D, strs2R, strs2); return md_scalar2(D + 1, dimsR, strs1R, (const float*)ptr1, strs2R, (const float*)ptr2); } /** * Calculate real part of the inner product between two complex arrays (without strides) * * return iptr1^H * iptr2 */ float md_zscalar_real(unsigned int D, const long dims[D], const complex float* ptr1, const complex float* ptr2) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); return md_zscalar_real2(D, dims, strs, ptr1, strs, ptr2); } /** * Calculate l2 norm of complex array (with strides) * * return sqrt(iptr^H * iptr) */ float md_znorm2(unsigned int D, const long dim[D], const long str[D], const complex float* ptr) { return sqrtf(md_zscalar_real2(D, dim, str, ptr, str, ptr)); // return sqrtf(crealf(md_zscalar2(D, dim, str, ptr, str, ptr))); } /** * Calculate l2 norm of complex array (without strides) * * return sqrt(iptr^H * iptr) */ float md_znorm(unsigned int D, const long dim[D], const complex float* ptr) { return sqrtf(md_zscalar_real(D, dim, ptr, ptr)); // return sqrtf(crealf(md_zscalar(D, dim, ptr, ptr))); } /** * Calculate absolute value. * */ void md_abs2(unsigned int D, const long dims[D], const long ostr[D], float* optr, const long istr[D], const float* iptr) { assert(optr != iptr); md_clear2(D, dims, ostr, optr, FL_SIZE); md_fmac2(D, dims, ostr, optr, istr, iptr, istr, iptr); // FIXME: should be cheaper md_sqrt2(D, dims, ostr, optr, ostr, optr); } /** * Calculate absolute value. * */ void md_abs(unsigned int D, const long dims[D], float* optr, const float* iptr) { make_2op_simple(md_abs2, D, dims, optr, iptr); } /** * Calculate absolute value. * */ void md_zabs2(unsigned int D, const long dims[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { #if 1 MAKE_Z2OP(zabs, D, dims, ostr, optr, istr, iptr); #else // FIXME: special case of md_rss assert(optr != iptr); md_clear2(D, dims, ostr, optr, CFL_SIZE); md_zfmacc2(D, dims, ostr, optr, istr, iptr, istr, iptr); #if 1 long dimsR[D + 1]; long strsR[D + 1]; real_from_complex_dims(D, dimsR, dims); real_from_complex_strides(D, strsR, ostr); //md_sqrt2(D, dimsR + 1, strsR + 1, (float*)optr, strsR + 1, (const float*)optr); // skipping imaginary part is expensive md_sqrt2(D + 1, dimsR, strsR, (float*)optr, strsR, (const float*)optr); #else md_zsqrt2(D, dims, ostr, optr, ostr, optr); #endif #endif } /** * Calculate absolute value. * */ void md_zabs(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr) { make_z2op_simple(md_zabs2, D, dims, optr, iptr); } /** * Calculate sum of absolute values. * */ float md_asum2(unsigned int D, const long dims[D], const long strs[D], const float* ptr) { #if 1 if (md_calc_blockdim(D, dims, strs, FL_SIZE) == D) { #ifdef USE_CUDA if (cuda_ondevice(ptr)) return gpu_ops.asum(md_calc_size(D, dims), ptr); #endif return cpu_ops.asum(md_calc_size(D, dims), ptr); } #endif float* tmp = md_alloc_sameplace(D, dims, FL_SIZE, ptr); long strs1[D]; md_calc_strides(D, strs1, dims, FL_SIZE); md_abs2(D, dims, strs1, tmp, strs, ptr); float ret = 0.; float* retp = &ret; #ifdef USE_CUDA if (cuda_ondevice(ptr)) retp = gpu_constant(&ret, FL_SIZE); #endif long dims0[D]; md_singleton_dims(D, dims0); md_axpy2(D, dims, MD_STRIDES(D, dims0, FL_SIZE), retp, 1., strs1, tmp); #ifdef USE_CUDA if (cuda_ondevice(ptr)) { md_copy(D, dims0, &ret, retp, FL_SIZE); md_free(retp); } #endif md_free(tmp); return ret; } /** * Calculate sum of absolute values. * */ float md_asum(unsigned int D, const long dims[D], const float* ptr) { return md_asum2(D, dims, MD_STRIDES(D, dims, FL_SIZE), ptr); } /** * Calculate sum of absolute values of complex numbers * where real and imaginary are separate elements of the sum. * (similar to BLAS L1 function). * */ float md_zasum2(unsigned int D, const long dims[D], const long strs[D], const complex float* ptr) { long dimsR[D + 1]; real_from_complex_dims(D, dimsR, dims); long strsR[D + 1]; real_from_complex_strides(D, strsR, strs); return md_asum2(D + 1, dimsR, strsR, (const float*)ptr); } /** * Calculate sum of absolute values of complex numbers * where real and imaginary are separate elements of the sum. * (similar to BLAS L1 function). * */ float md_zasum(unsigned int D, const long dims[D], const complex float* ptr) { return md_zasum2(D, dims, MD_STRIDES(D, dims, CFL_SIZE), ptr); } /** * Calculate l1 norm of complex array (with strides) */ float md_z1norm2(unsigned int D, const long dims[D], const long strs[D], const complex float* ptr) { complex float* tmp = md_alloc_sameplace(D, dims, CFL_SIZE, ptr); md_zabs2(D, dims, MD_STRIDES(D, dims, CFL_SIZE), tmp, strs, ptr); float val = md_zasum(D, dims, tmp); md_free(tmp); return val; } /** * Calculate l1 norm of complex array (without strides) */ float md_z1norm(unsigned int D, const long dim[D], const complex float* ptr) { return md_z1norm2(D, dim, MD_STRIDES(D, dim, CFL_SIZE), ptr); } /** * Root of sum of squares along selected dimensions * * @param dims -- full dimensions of src image * @param flags -- bitmask for applying the root of sum of squares, ie the dimensions that will not stay */ void md_rss(unsigned int D, const long dims[D], unsigned int flags, float* dst, const float* src) { long str1[D]; long str2[D]; long dims2[D]; md_select_dims(D, ~flags, dims2, dims); md_calc_strides(D, str1, dims, FL_SIZE); md_calc_strides(D, str2, dims2, FL_SIZE); md_clear(D, dims2, dst, FL_SIZE); md_fmac2(D, dims, str2, dst, str1, src, str1, src); md_sqrt(D, dims2, dst, dst); } /** * Sum of squares along selected dimensions * * @param dims -- full dimensions of src image * @param flags -- bitmask for applying the root of sum of squares, i.e. the dimensions that will not stay */ void md_zss(unsigned int D, const long dims[D], unsigned int flags, complex float* dst, const complex float* src) { long str1[D]; long str2[D]; long dims2[D]; md_select_dims(D, ~flags, dims2, dims); md_calc_strides(D, str1, dims, CFL_SIZE); md_calc_strides(D, str2, dims2, CFL_SIZE); md_clear(D, dims2, dst, CFL_SIZE); md_zfmacc2(D, dims, str2, dst, str1, src, str1, src); } /** * Root of sum of squares along selected dimensions * * @param dims -- full dimensions of src image * @param flags -- bitmask for applying the root of sum of squares, i.e. the dimensions that will not stay */ void md_zrss(unsigned int D, const long dims[D], unsigned int flags, complex float* dst, const complex float* src) { long dims2[D]; md_select_dims(D, ~flags, dims2, dims); #if 1 md_zss(D, dims, flags, dst, src); #if 1 long dims2R[D + 1]; real_from_complex_dims(D, dims2R, dims2); md_sqrt(D + 1, dims2R, (float*)dst, (const float*)dst); #else md_zsqrt(D, dims2, dst, dst); #endif #else long dimsR[D + 1]; real_from_complex_dims(D, dimsR, dims); md_rrss(D + 1, dimsR, (flags << 1), (float*)dst, (const float*)src); #endif } /** * Compute variance or standard deviation along selected dimensions (with strides) * * @param dims -- full dimensions of src image * @param flags -- bitmask for calculating var/std, i.e. the dimensions that will not stay * @param variance -- true if computing variance, false if computing standard deviation */ static void md_zvarstd2(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr, bool variance) { long odims[D]; long fdims[D]; md_select_dims(D, ~flags, odims, dims); md_select_dims(D, flags, fdims, dims); complex float* tmp = md_alloc_sameplace(D, dims, CFL_SIZE, iptr); md_zavg2(D, dims, flags, ostr, optr, istr, iptr); md_zsub2(D, dims, istr, tmp, istr, iptr, ostr, optr); double scale = variance ? md_calc_size(D, fdims) - 1. : sqrtf(md_calc_size(D, fdims) - 1.); (variance ? md_zss : md_zrss)(D, dims, flags, optr, tmp); md_zsmul2(D, odims, ostr, optr, ostr, optr, 1. / scale); md_free(tmp); } /** * Compute variance along selected dimensions (without strides) * * @param dims -- full dimensions of src image * @param flags -- bitmask for calculating variance, i.e. the dimensions that will not stay */ void md_zvar(unsigned int D, const long dims[D], unsigned int flags, complex float* optr, const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); md_zvar2(D, dims, flags, MD_STRIDES(D, odims, CFL_SIZE), optr, MD_STRIDES(D, dims, CFL_SIZE), iptr); } /** * Compute variance along selected dimensions (with strides) * * @param dims -- full dimensions of src image * @param flags -- bitmask for calculating variance, i.e. the dimensions that will not stay */ void md_zvar2(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { md_zvarstd2(D, dims, flags, ostr, optr, istr, iptr, true); } /** * Compute standard deviation along selected dimensions (without strides) * * @param dims -- full dimensions of src image * @param flags -- bitmask for calculating standard deviation, i.e. the dimensions that will not stay */ void md_zstd(unsigned int D, const long dims[D], unsigned int flags, complex float* optr, const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); md_zvarstd2(D, dims, flags, MD_STRIDES(D, odims, CFL_SIZE), optr, MD_STRIDES(D, dims, CFL_SIZE), iptr, false); } /** * Compute standard deviation along selected dimensions (with strides) * * @param dims -- full dimensions of src image * @param flags -- bitmask for calculating standard deviation, i.e. the dimensions that will not stay */ void md_zstd2(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { md_zvarstd2(D, dims, flags, ostr, optr, istr, iptr, false); } /** * Average along flagged dimensions (without strides) * * @param dims -- full dimensions of iptr * @param flags -- bitmask for applying the average, i.e. the dimensions that will not stay */ void md_zavg(unsigned int D, const long dims[D], unsigned int flags, complex float* optr, const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); md_zavg2(D, dims, flags, MD_STRIDES(D, odims, CFL_SIZE), optr, MD_STRIDES(D, dims, CFL_SIZE), iptr); } /** * Average along flagged dimensions (with strides) * * @param dims -- full dimensions of iptr * @param flags -- bitmask for applying the average, i.e. the dimensions that will not stay */ void md_zavg2(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); md_clear(D, odims, optr, CFL_SIZE); //FIXME: this is faster #if 1 complex float* o = md_alloc_sameplace(1, MD_DIMS(1), CFL_SIZE, optr); md_zfill(1, MD_DIMS(1), o, 1.); long ss[D]; md_singleton_strides(D, ss); md_zfmac2(D, dims, ostr, optr, istr, iptr, ss, o); md_free(o); #else md_zaxpy2(D, dims, ostr, optr, 1., istr, iptr); #endif long sdims[D]; md_select_dims(D, flags, sdims, dims); long scale = md_calc_size(D, sdims); if (scale != 0.) md_zsmul(D, odims, optr, optr, 1. / scale); } /** * Weighted average along flagged dimensions (without strides) * * @param dims -- full dimensions of iptr * @param flags -- bitmask for applying the weighted average, i.e. the dimensions that will not stay */ void md_zwavg(unsigned int D, const long dims[D], unsigned int flags, complex float* optr, const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); md_zwavg2(D, dims, flags, MD_STRIDES(D, odims, CFL_SIZE), optr, MD_STRIDES(D, dims, CFL_SIZE), iptr); } /** * Weighted average along flagged dimensions (with strides) * * @param dims -- full dimensions of iptr * @param flags -- bitmask for applying the weighted average, i.e. the dimensions that will not stay */ void md_zwavg2(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); complex float* weights = md_alloc_sameplace(D, odims, CFL_SIZE, iptr); md_zwavg2_core1(D, dims, flags, ostr, weights, istr, iptr); md_zwavg2_core2(D, dims, flags, ostr, optr, weights, istr, iptr); md_free(weights); } /** * Compute weights for weighted average * * @param iptr input array to be averaged * @param weights output weights */ void md_zwavg2_core1(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* weights, const long istr[D], const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); complex float* pattern = md_alloc_sameplace(D, dims, CFL_SIZE, iptr); long onestrs[D]; md_singleton_strides(D, onestrs); md_zcmp2(D, dims, istr, pattern, istr, iptr, onestrs, &(complex float){ 0. }); md_zsub2(D, dims, istr, pattern, onestrs, &(complex float){ 1. }, istr, pattern); md_clear2(D, odims, ostr, weights, CFL_SIZE); md_zaxpy2(D, dims, ostr, weights, 1., istr, pattern); md_free(pattern); } /** * Weighted average along flagged dimensions with given weights * * @param weights precomputed weights for averaging * @param optr output array after averaging */ void md_zwavg2_core2(unsigned int D, const long dims[D], unsigned int flags, const long ostr[D], complex float* optr, const complex float* weights, const long istr[D], const complex float* iptr) { long odims[D]; md_select_dims(D, ~flags, odims, dims); md_clear2(D, odims, ostr, optr, CFL_SIZE); md_zaxpy2(D, dims, ostr, optr, 1., istr, iptr); md_zdiv(D, odims, optr, optr, weights); } /** * Fill complex array with value (with strides). * */ void md_zfill2(unsigned int D, const long dim[D], const long str[D], complex float* ptr, complex float val) { md_fill2(D, dim, str, ptr, &val, CFL_SIZE); } /** * Fill complex array with value (without strides). * */ extern void md_zfill(unsigned int D, const long dim[D], complex float* ptr, complex float val) { md_fill(D, dim, ptr, &val, CFL_SIZE); } /** * Step (2) of Soft Thresholding multi-dimensional arrays, y = ST(x, lambda) * 2) computes resid = MAX( (abs(x) - lambda)/abs(x), 0 ) (with strides) * * @param D number of dimensions * @param dim dimensions of input/output * @param lambda threshold parameter * @param ostr output strides * @param optr pointer to output, y * @param istr input strides * @param iptr pointer to input, abs(x) */ void md_zsoftthresh_half2(unsigned int D, const long dim[D], float lambda, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { NESTED(void, nary_zsoftthresh_half, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zsoftthresh_half(data->size, lambda, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr, iptr, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zsoftthresh_half); } /** * Step (2) of Soft Thresholding multi-dimensional arrays, y = ST(x, lambda) * 2) computes resid = MAX( (abs(x) - lambda)/abs(x), 0 ) (with strides) * * @param D number of dimensions * @param dim dimensions of input/output * @param lambda threshold parameter * @param ostr output strides * @param optr pointer to output, y * @param istr input strides * @param iptr pointer to input, abs(x) */ void md_softthresh_half2(unsigned int D, const long dim[D], float lambda, const long ostr[D], float* optr, const long istr[D], const float* iptr) { NESTED(void, nary_softthresh_half, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->softthresh_half(data->size, lambda, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr, iptr, (size_t[2]){ FL_SIZE, FL_SIZE }, nary_softthresh_half); } /** * Step (1) of Soft Thresholding multi-dimensional arrays, y = ST(x, lambda) * 1) computes resid = MAX( (abs(x) - lambda)/abs(x), 0 ) (without strides) * * @param D number of dimensions * @param dim dimensions of input/output * @param lambda threshold parameter * @param optr pointer to output, y * @param iptr pointer to input, x */ void md_zsoftthresh_half(unsigned int D, const long dim[D], float lambda, complex float* optr, const complex float* iptr) { long str[D]; md_calc_strides(D, str, dim, CFL_SIZE); md_zsoftthresh_half2(D, dim, lambda, str, optr, str, iptr); } void md_softthresh_core2(unsigned int D, const long dims[D], float lambda, unsigned int flags, float* tmp_norm, const long ostrs[D], float* optr, const long istrs[D], const float* iptr) { long norm_dims[D]; long norm_strs[D]; md_select_dims(D, ~flags, norm_dims, dims); md_calc_strides(D, norm_strs, norm_dims, FL_SIZE); md_rss(D, dims, flags, tmp_norm, iptr); md_softthresh_half2(D, norm_dims, lambda, norm_strs, tmp_norm, norm_strs, tmp_norm); md_mul2(D, dims, ostrs, optr, norm_strs, tmp_norm, istrs, iptr); } /** * Soft Thresholding for floats (with strides) * * optr = ST(iptr, lambda) */ void md_softthresh2(unsigned int D, const long dims[D], float lambda, unsigned int flags, const long ostrs[D], float* optr, const long istrs[D], const float* iptr) { NESTED(void, nary_softthresh, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->softthresh(data->size, lambda, ptr[0], ptr[1]); }; if (0 == flags) { optimized_twoop_oi(D, dims, ostrs, optr, istrs, iptr, (size_t[2]){ FL_SIZE, FL_SIZE }, nary_softthresh); return; } long norm_dims[D]; md_select_dims(D, ~flags, norm_dims, dims); float* tmp_norm = md_alloc_sameplace(D, norm_dims, FL_SIZE, iptr); md_softthresh_core2(D, dims, lambda, flags, tmp_norm, ostrs, optr, istrs, iptr); md_free(tmp_norm); } /** * Soft Thresholding for floats (without strides) * * optr = ST(iptr, lambda) */ void md_softthresh(unsigned int D, const long dims[D], float lambda, unsigned int flags, float* optr, const float* iptr) { long str[D]; md_calc_strides(D, str, dims, FL_SIZE); md_softthresh2(D, dims, lambda, flags, str, optr, str, iptr); } void md_zsoftthresh_core2(unsigned int D, const long dims[D], float lambda, unsigned int flags, complex float* tmp_norm, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { long norm_dims[D]; long norm_strs[D]; md_select_dims(D, ~flags, norm_dims, dims); md_calc_strides(D, norm_strs, norm_dims, CFL_SIZE); md_zrss(D, dims, flags, tmp_norm, iptr); md_zsoftthresh_half2(D, norm_dims, lambda, norm_strs, tmp_norm, norm_strs, tmp_norm); md_zmul2(D, dims, ostrs, optr, norm_strs, tmp_norm, istrs, iptr); } /** * Soft thresholding using norm along arbitrary dimension (with strides) * * y = ST(x, lambda) * 1) computes resid = MAX((norm(x) - lambda) / norm(x), 0) * 2) multiplies y = resid * x * * @param D number of dimensions * @param dims dimensions of input/output * @param lambda threshold parameter * @param flags jointly thresholded dimensions * @param optr destination -- soft thresholded values * @param iptr source -- values to be soft thresholded */ void md_zsoftthresh2(unsigned int D, const long dims[D], float lambda, unsigned int flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { NESTED(void, nary_zsoftthresh, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zsoftthresh(data->size, lambda, ptr[0], ptr[1]); }; if (0 == flags) { optimized_twoop_oi(D, dims, ostrs, optr, istrs, iptr, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zsoftthresh); return; } long norm_dims[D]; md_select_dims(D, ~flags, norm_dims, dims); complex float* tmp_norm = md_alloc_sameplace(D, norm_dims, CFL_SIZE, iptr); md_zsoftthresh_core2(D, dims, lambda, flags, tmp_norm, ostrs, optr, istrs, iptr); md_free(tmp_norm); } /** * Soft thresholding using norm along arbitrary dimension (without strides) * * y = ST(x, lambda) * 1) computes resid = MAX((norm(x) - lambda) / norm(x), 0) * 2) multiplies y = resid * x * * @param D number of dimensions * @param dims dimensions of input/output * @param lambda threshold parameter * @param flags jointly thresholded dimensions * @param optr destination -- soft thresholded values * @param iptr source -- values to be soft thresholded */ void md_zsoftthresh(unsigned int D, const long dims[D], float lambda, unsigned int flags, complex float* optr, const complex float* iptr) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zsoftthresh2(D, dims, lambda, flags, strs, optr, strs, iptr); } /** * Produces a mask (1s and 0s) of the non-zero support of a hard thresholded input vector * Multi-dimensional operation with strides * Hard thresholding is performed by selection of the k largest elements in input. * * @param D number of dimensions * @param dim dimensions of input/output * @param k threshold parameter * @param flags flags for joint operation * @param ostr output strides * @param optr pointer to output * @param istr input strides * @param iptr pointer to input */ void md_zhardthresh_mask2(unsigned int D, const long dim[D], unsigned int k, unsigned int flags, complex float* tmp_norm, const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { NESTED(void, nary_zhardthresh_mask, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zhardthresh_mask(data->size, k, ptr[0], ptr[1]); }; if (0 == flags) { optimized_twoop_oi(D, dim, ostr, optr, istr, iptr, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zhardthresh_mask); return; } long norm_dims[D]; long norm_strs[D]; md_select_dims(D, ~flags, norm_dims, dim); md_calc_strides(D, norm_strs, norm_dims, CFL_SIZE); md_zrss(D, dim, flags, tmp_norm, iptr); optimized_twoop_oi(D, norm_dims, norm_strs, tmp_norm, norm_strs, tmp_norm, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zhardthresh_mask); md_copy2(D, dim, ostr, optr, norm_strs, tmp_norm, CFL_SIZE); } /** * Produces a mask (1s and 0s) of the non-zero support of a hard thresholded input vector * Multi-dimensional operation using the same strides for input and output. * Hard thresholding is performed by selection of the k largest elements in input. * * @param D number of dimensions * @param dim dimensions of input/output * @param k threshold parameter * @param optr pointer to output * @param iptr pointer to input */ void md_zhardthresh_mask(unsigned int D, const long dim[D], unsigned int k, unsigned int flags, complex float* optr, const complex float* iptr) { long str[D]; md_calc_strides(D, str, dim, CFL_SIZE); long norm_dims[D]; md_select_dims(D, ~flags, norm_dims, dim); complex float* tmp_norm = md_alloc_sameplace(D, norm_dims, CFL_SIZE, iptr); md_zhardthresh_mask2(D, dim, k, flags, tmp_norm, str, optr, str, iptr); md_free(tmp_norm); } /** * Joint Hard thresholding (with strides) * Performs hard thresholding to the norm along dimension specified by flags * Applies the support of thresholded norm to every vector along that dimension * Hard thresholding refers to the selection of the k largest elements in vector. * * @param D number of dimensions * @param dims dimensions of input/output * @param k threshold (sorted) index * @param flags jointly thresholded dimensions * @param tmp_norm temporary array for joint operation * @param ostrs destination strides * @param optr destination -- thresholded values * @param istrs source strides * @param iptr source -- values to be thresholded */ void md_zhardthresh_joint2(unsigned int D, const long dims[D], unsigned int k, unsigned int flags, complex float* tmp_norm, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { long norm_dims[D]; long norm_strs[D]; md_select_dims(D, ~flags, norm_dims, dims); md_calc_strides(D, norm_strs, norm_dims, CFL_SIZE); md_zrss(D, dims, flags, tmp_norm, iptr); NESTED(void, nary_zhardthresh_mask, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zhardthresh_mask(data->size, k, ptr[0], ptr[1]); }; optimized_twoop_oi(D, norm_dims, norm_strs, tmp_norm, norm_strs, tmp_norm, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zhardthresh_mask); md_zmul2(D, dims, ostrs, optr, norm_strs, tmp_norm, istrs, iptr); } /** * Hard thresholding (with strides) * * y = HT(x, k), selects k largest elements of x * computes y = x * (abs(x) > t(k)), * k = threshold index of sorted x, t(k)= value of sorted x at k * * @param D number of dimensions * @param dims dimensions of input/output * @param k threshold (sorted) index * @param flags jointly thresholded dimensions * @param tmp_norm temporary array for joint operation * @param ostrs destination strides * @param optr destination -- thresholded values * @param istrs source strides * @param iptr source -- values to be thresholded */ void md_zhardthresh2(unsigned int D, const long dims[D], unsigned int k, unsigned int flags, const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr) { NESTED(void, nary_zhardthresh, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zhardthresh(data->size, k, ptr[0], ptr[1]); }; if (0 == flags) { optimized_twoop_oi(D, dims, ostrs, optr, istrs, iptr, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zhardthresh); return; } long norm_dims[D]; md_select_dims(D, ~flags, norm_dims, dims); complex float* tmp_norm = md_alloc_sameplace(D, norm_dims, CFL_SIZE, iptr); md_zhardthresh_joint2(D, dims, k, flags, tmp_norm, ostrs, optr, istrs,iptr); md_free(tmp_norm); } /** * Hard thresholding (without strides) * * y = HT(x, k), select k largest elements. * * @param D number of dimensions * @param dims dimensions of input/output * @param k threshold parameter * @param flags jointly thresholded dimensions * @param optr destination -- thresholded values * @param iptr source -- values to be thresholded */ void md_zhardthresh(unsigned int D, const long dims[D], unsigned int k, unsigned int flags, complex float* optr, const complex float* iptr) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zhardthresh2(D, dims, k, flags, strs, optr, strs, iptr); } /** * Elementwise minimum of input and scalar (with strides) * * optr = min(val, iptr) */ void md_smin2(unsigned int D, const long dim[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float val) { float* tmp = md_alloc_sameplace(D, dim, FL_SIZE, iptr); md_slessequal2(D, dim, ostr, tmp, istr, iptr, val); md_mul2(D, dim, ostr, optr, istr, iptr, istr, tmp); md_free(tmp); } /** * Elementwise minimum of input and scalar (without strides) * * optr = min(val, iptr) */ void md_smin(unsigned int D, const long dim[D], float* optr, const float* iptr, float val) { long str[D]; md_calc_strides(D, str, dim, FL_SIZE); md_smin2(D, dim, str, optr, str, iptr, val); } /** * Elementwise maximum of input and scalar (with strides) * * optr = max(val, iptr) */ void md_smax2(unsigned int D, const long dim[D], const long ostr[D], float* optr, const long istr[D], const float* iptr, float val) { #if 0 // slow on GPU due to make_3op_scalar #if 0 float* tmp = md_alloc_sameplace(D, dim, FL_SIZE, iptr); md_sgreatequal2(D, dim, ostr, tmp, istr, iptr, val); md_mul2(D, dim, ostr, optr, istr, iptr, istr, tmp); md_free(tmp); #else make_3op_scalar(md_max2, D, dim, ostr, optr, istr, iptr, val); #endif #else (void)0; NESTED(void, nary_smax, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->smax(data->size, val, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr, iptr, (size_t[2]){ FL_SIZE, FL_SIZE }, nary_smax); #endif } /** * Elementwise maximum of input and scalar (with strides) * * optr = max(val, iptr) */ void md_zsmax2(unsigned int D, const long dim[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr, float val) { #if 0 complex float* tmp = md_alloc_sameplace(D, dim, CFL_SIZE, iptr); md_zsgreatequal2(D, dim, ostr, tmp, istr, iptr, val); md_zmul2(D, dim, ostr, optr, istr, iptr, istr, tmp); md_free(tmp); #else #if 0 make_z3op_scalar(md_zmax2, D, dim, ostr, optr, istr, iptr, val); #else // FIXME: we should rather optimize md_zmul2 for this case NESTED(void, nary_zsmax, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zsmax(data->size, val, ptr[0], ptr[1]); }; optimized_twoop_oi(D, dim, ostr, optr, istr, iptr, (size_t[2]){ CFL_SIZE, CFL_SIZE }, nary_zsmax); #endif #endif } /** * Elementwise maximum of input and scalar (without strides) * * optr = max(val, iptr) */ void md_zsmax(unsigned int D, const long dim[D], complex float* optr, const complex float* iptr, float val) { long str[D]; md_calc_strides(D, str, dim, CFL_SIZE); md_zsmax2(D, dim, str, optr, str, iptr, val); } /** * Elementwise minimum of input and scalar (without strides) * * optr = max(val, iptr) */ void md_smax(unsigned int D, const long dim[D], float* optr, const float* iptr, float val) { long str[D]; md_calc_strides(D, str, dim, FL_SIZE); md_smax2(D, dim, str, optr, str, iptr, val); } static void md_fdiff_core2(unsigned int D, const long dims[D], unsigned int d, bool dir, const long ostr[D], float* out, const long istr[D], const float* in) { long pos[D]; md_set_dims(D, pos, 0); pos[d] = dir ? 1 : -1; md_circ_shift2(D, dims, pos, ostr, out, istr, in, FL_SIZE); md_sub2(D, dims, ostr, out, istr, in, ostr, out); } /** * Compute finite (forward) differences along selected dimensions. * */ void md_fdiff2(unsigned int D, const long dims[D], unsigned int d, const long ostr[D], float* out, const long istr[D], const float* in) { md_fdiff_core2(D, dims, d, true, ostr, out, istr, in); } /** * Compute finite differences along selected dimensions. * */ void md_fdiff(unsigned int D, const long dims[D], unsigned int d, float* out, const float* in) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_fdiff2(D, dims, d, strs, out, strs, in); } /** * Compute finite (backward) differences along selected dimensions. * */ void md_fdiff_backwards2(unsigned int D, const long dims[D], unsigned int d, const long ostr[D], float* out, const long istr[D], const float* in) { md_fdiff_core2(D, dims, d, false, ostr, out, istr, in); } /** * Compute finite (backward) differences along selected dimensions. * */ void md_fdiff_backwards(unsigned int D, const long dims[D], unsigned int d, float* out, const float* in) { long strs[D]; md_calc_strides(D, strs, dims, FL_SIZE); md_fdiff_backwards2(D, dims, d, strs, out, strs, in); } static void md_zfdiff_core2(unsigned int D, const long dims[D], unsigned int d, bool dir, const long ostr[D], complex float* out, const long istr[D], const complex float* in) { // we could also implement in terms of md_fdiff2 long pos[D]; md_set_dims(D, pos, 0); pos[d] = dir ? 1 : -1; md_circ_shift2(D, dims, pos, ostr, out, istr, in, CFL_SIZE); md_zsub2(D, dims, ostr, out, istr, in, ostr, out); } /** * Compute finite (forward) differences along selected dimensions. * */ void md_zfdiff2(unsigned int D, const long dims[D], unsigned int d, const long ostr[D], complex float* out, const long istr[D], const complex float* in) { md_zfdiff_core2(D, dims, d, true, ostr, out, istr, in); } /** * Compute finite (backward) differences along selected dimensions. * */ void md_zfdiff_backwards2(unsigned int D, const long dims[D], unsigned int d, const long ostr[D], complex float* out, const long istr[D], const complex float* in) { md_zfdiff_core2(D, dims, d, false, ostr, out, istr, in); } /** * Compute finite (forward) differences along selected dimensions. * */ void md_zfdiff(unsigned int D, const long dims[D], unsigned int d, complex float* out, const complex float* in) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zfdiff2(D, dims, d, strs, out, strs, in); } /** * Compute finite (backward) differences along selected dimensions. * */ void md_zfdiff_backwards(unsigned int D, const long dims[D], unsigned int d, complex float* out, const complex float* in) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zfdiff_backwards2(D, dims, d, strs, out, strs, in); } // DO NOT USE DIRECTLY - this is used internally by fftmod from fft.[ch] void md_zfftmod2(unsigned int D, const long dims[D], const long ostrs[D], complex float* optr, const long istrs[D], const complex float* iptr, bool inv, double phase) { assert(D > 0); assert((CFL_SIZE == ostrs[0]) && (CFL_SIZE == istrs[0])); unsigned int N = dims[0]; NESTED(void, nary_zfftmod, (struct nary_opt_data_s* data, void* ptr[])) { data->ops->zfftmod(data->size, ptr[0], ptr[1], N, inv, phase); }; optimized_twoop_oi(D - 1, dims + 1, ostrs + 1, optr, istrs + 1, iptr, (size_t[2]){ N * CFL_SIZE, N * CFL_SIZE }, nary_zfftmod); } void md_zfftmod(unsigned int D, const long dims[D], complex float* optr, const complex float* iptr, bool inv, double phase) { long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); md_zfftmod2(D, dims, strs, optr, strs, iptr, inv, phase); } /** * Sum along selected dimensions * * @param dims -- full dimensions of src image * @param flags -- bitmask for applying the sum, i.e. the dimensions that will not stay */ void md_zsum(unsigned int D, const long dims[D], unsigned int flags, complex float* dst, const complex float* src) { long str1[D]; long str2[D]; long dims2[D]; md_select_dims(D, ~flags, dims2, dims); md_calc_strides(D, str1, dims, CFL_SIZE); md_calc_strides(D, str2, dims2, CFL_SIZE); complex float* ones = md_alloc_sameplace(D, dims, CFL_SIZE, dst); md_zfill(D, dims, ones, 1.); md_clear(D, dims2, dst, CFL_SIZE); md_zfmac2(D, dims, str2, dst, str1, src, str1, ones); md_free(ones); } bart-0.5.00/src/num/flpmath.h000066400000000000000000000743031353046746100157360ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2015-2019. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __FLPMATH #define __FLPMATH #include "misc/cppwrap.h" #define CFL_SIZE sizeof(_Complex float) #define FL_SIZE sizeof(float) #define CDL_SIZE sizeof(_Complex double) #define DL_SIZE sizeof(double) extern void md_mul2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_mul(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_zrmul2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zrmul(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zmul2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zmul(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zdiv2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zdiv(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zdiv_reg2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2, _Complex float lambda); extern void md_zdiv_reg(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2, _Complex float lambda); extern void md_div2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_div(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_zmulc2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zmulc(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zsmul2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr, _Complex float val); extern void md_zsmul(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr, _Complex float val); extern void md_smul2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr, float val); extern void md_smul(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr, float val); extern void md_zpow2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zpow(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_pow2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_pow(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_sqrt2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr); extern void md_sqrt(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr); extern void md_zsqrt2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1); extern void md_zsqrt(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1); extern void md_zspow2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr, _Complex float val); extern void md_zspow(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr, _Complex float val); extern void md_zaxpy2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, _Complex float val, const long istr1[__VLA(D)], const _Complex float* iptr1); extern void md_zaxpy(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, _Complex float val, const _Complex float* iptr1); extern void md_axpy2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, float val, const long istr1[__VLA(D)], const float* iptr1); extern void md_axpy(unsigned int D, const long dim[__VLA(D)], float* optr, float val, const float* iptr); extern void md_zfmac2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zfmac(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_tenmul_dims(unsigned int D, long max_dims[__VLA(D)], const long out_dims[__VLA(D)], const long in1_dims[__VLA(D)], const long in2_dims[__VLA(D)]); extern void md_ztenmul2(unsigned int D, const long max_dims[__VLA(D)], const long out_strs[__VLA(D)], _Complex float* out, const long in1_strs[__VLA(D)], const _Complex float* in1, const long in2_strs[__VLA(D)], const _Complex float* in2); extern void md_ztenmul(unsigned int D, const long out_dims[__VLA(D)], _Complex float* out, const long in1_dims[__VLA(D)], const _Complex float* in1, const long in2_dims[__VLA(D)], const _Complex float* int2); extern void md_ztenmulc2(unsigned int D, const long max_dims[__VLA(D)], const long out_strs[__VLA(D)], _Complex float* out, const long in1_strs[__VLA(D)], const _Complex float* in1, const long in2_strs[__VLA(D)], const _Complex float* in2); extern void md_ztenmulc(unsigned int D, const long out_dims[__VLA(D)], _Complex float* out, const long in1_dims[__VLA(D)], const _Complex float* in1, const long in2_dims[__VLA(D)], const _Complex float* int2); extern void md_zconv2(int N, unsigned long flags, const long odims[__VLA(N)], const long ostrs[__VLA(N)], _Complex float* out, const long kdims[__VLA(N)], const long kstrs[__VLA(N)], const _Complex float* krn, const long idims[__VLA(N)], const long istrs[__VLA(N)], const _Complex float* in); extern void md_zconv(int N, unsigned long flags, const long odims[__VLA(N)], _Complex float* out, const long kdims[__VLA(N)], const _Complex float* krn, const long idims[__VLA(N)], const _Complex float* in); extern void md_matmul_dims(unsigned int D, long max_dims[__VLA(D)], const long out_dims[__VLA(D)], const long mat_dims[__VLA(D)], const long in_dims[__VLA(D)]); extern void md_zmatmul2(unsigned int D, const long out_dims[__VLA(D)], const long out_strs[__VLA(D)], _Complex float* dst, const long mat_dims[__VLA(D)], const long mat_strs[__VLA(D)], const _Complex float* mat, const long in_dims[__VLA(D)], const long in_strs[__VLA(D)], const _Complex float* src); extern void md_zmatmul(unsigned int D, const long out_dims[__VLA(D)], _Complex float* dst, const long mat_dims[__VLA(D)], const _Complex float* mat, const long in_dims[__VLA(D)], const _Complex float* src); extern void md_zmatmulc2(unsigned int D, const long out_dims[__VLA(D)], const long out_strs[__VLA(D)], _Complex float* dst, const long mat_dims[__VLA(D)], const long mat_strs[__VLA(D)], const _Complex float* mat, const long in_dims[__VLA(D)], const long in_strs[__VLA(D)], const _Complex float* src); extern void md_zmatmulc(unsigned int D, const long out_dims[__VLA(D)], _Complex float* dst, const long mat_dims[__VLA(D)], const _Complex float* mat, const long in_dims[__VLA(D)], const _Complex float* src); extern void md_fmac2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_fmac(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_zfmacc2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zfmacc(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zfmaccD(unsigned int D, const long dim[__VLA(D)], _Complex double* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zfmacD2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex double* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zfmacD(unsigned int D, const long dim[__VLA(D)], _Complex double* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_fmacD2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], double* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_fmacD(unsigned int D, const long dim[__VLA(D)], double* optr, const float* iptr1, const float* iptr2); extern void md_zfmaccD2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex double* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zfmaccD(unsigned int D, const long dim[__VLA(D)], _Complex double* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zadd2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zadd(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zsadd2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr, _Complex float val); extern void md_zsadd(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr, _Complex float val); extern void md_zsub2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zsub(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_add2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_add(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_sadd2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr, float val); extern void md_sadd(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr, float val); extern void md_sub2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_sub(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_zphsr(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zphsr2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_abs(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr); extern void md_abs2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr); extern void md_zabs(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zabs2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zmax(unsigned int D, const long dims[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zmax2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_max(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_max2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_min(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_min2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr); extern void md_zsoftthresh_half2(unsigned int D, const long dim[__VLA(D)], float lambda, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zsoftthresh_half(unsigned int D, const long dim[__VLA(D)], float lambda, _Complex float* optr, const _Complex float* iptr); extern void md_softthresh_half2(unsigned int D, const long dim[__VLA(D)], float lambda, const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr); extern void md_softthresh_half(unsigned int D, const long dim[__VLA(D)], float lambda, float* optr, const float* iptr); extern void md_softthresh2(unsigned int D, const long dim[__VLA(D)], float lambda, unsigned int flags, const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr); extern void md_softthresh(unsigned int D, const long dim[__VLA(D)], float lambda, unsigned int flags, float* optr, const float* iptr); extern void md_softthresh_core2(unsigned int D, const long dims[__VLA(D)], float lambda, unsigned int flags, float* tmp_norm, const long ostrs[__VLA(D)], float* optr, const long istrs[__VLA(D)], const float* iptr); extern void md_zsoftthresh_core2(unsigned int D, const long dims[__VLA(D)], float lambda, unsigned int flags, _Complex float* tmp_norm, const long ostrs[__VLA(D)], _Complex float* optr, const long istrs[__VLA(D)], const _Complex float* iptr); extern void md_zsoftthresh2(unsigned int D, const long dim[__VLA(D)], float lambda, unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zsoftthresh(unsigned int D, const long dim[__VLA(D)], float lambda, unsigned int flags, _Complex float* optr, const _Complex float* iptr); void md_zhardthresh_mask2(unsigned int D, const long dim[__VLA(D)], unsigned int k, unsigned int flags, _Complex float* tmp_norm, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zhardthresh_mask(unsigned int D, const long dim[__VLA(D)], unsigned int k, unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zhardthresh_joint2(unsigned int D, const long dims[__VLA(D)], unsigned int k, unsigned int flags, _Complex float* tmp_norm, const long ostrs[__VLA(D)], _Complex float* optr, const long istrs[__VLA(D)], const _Complex float* iptr); extern void md_zhardthresh2(unsigned int D, const long dims[__VLA(D)], unsigned int k, unsigned int flags, const long ostrs[__VLA(D)], _Complex float* optr, const long istrs[__VLA(D)], const _Complex float* iptr); extern void md_zhardthresh(unsigned int D, const long dims[__VLA(D)], unsigned int k, unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zconj(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zconj2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zreal(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zreal2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zimag(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zimag2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zcmp(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zcmp2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zexpj(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zexpj2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zexp(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zexp2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zarg(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr); extern void md_zarg2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zlessequal(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zlessequal2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_lessequal(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_lessequal2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_slessequal(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr, float val); extern void md_slessequal2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr, float val); extern void md_zgreatequal(unsigned int D, const long dims[__VLA(D)], _Complex float* optr, const _Complex float* iptr1, const _Complex float* iptr2); extern void md_zgreatequal2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr1[__VLA(D)], const _Complex float* iptr1, const long istr2[__VLA(D)], const _Complex float* iptr2); extern void md_zsgreatequal(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr, float val); extern void md_zsgreatequal2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr, float val); extern void md_greatequal(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr1, const float* iptr2); extern void md_greatequal2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr1[__VLA(D)], const float* iptr1, const long istr2[__VLA(D)], const float* iptr2); extern void md_sgreatequal(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr, float val); extern void md_sgreatequal2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr, float val); extern float md_znorm2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const _Complex float* ptr); extern float md_znorm(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr); extern _Complex float md_zscalar2(unsigned int D, const long dim[__VLA(D)], const long str1[__VLA(D)], const _Complex float* ptr1, const long str2[__VLA(D)], const _Complex float* ptr2); extern _Complex float md_zscalar(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr1, const _Complex float* ptr2); extern float md_zscalar_real2(unsigned int D, const long dim[__VLA(D)], const long str1[__VLA(D)], const _Complex float* ptr1, const long str2[__VLA(D)], const _Complex float* ptr2); extern float md_zscalar_real(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr1, const _Complex float* ptr2); extern float md_asum2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const float* ptr); extern float md_asum(unsigned int D, const long dim[__VLA(D)], const float* ptr); extern float md_zasum2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const _Complex float* ptr); extern float md_zasum(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr); extern float md_z1norm2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const _Complex float* ptr); extern float md_z1norm(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr); extern float md_asum2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const float* ptr); extern float md_asum(unsigned int D, const long dim[__VLA(D)], const float* ptr); extern float md_zasum2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const _Complex float* ptr); extern float md_zasum(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr); extern float md_z1norm2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const _Complex float* ptr); extern float md_z1norm(unsigned int D, const long dim[__VLA(D)], const _Complex float* ptr); extern float md_norm2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], const float* ptr); extern float md_norm(unsigned int D, const long dim[__VLA(D)], const float* ptr); extern float md_scalar2(unsigned int D, const long dim[__VLA(D)], const long str1[__VLA(D)], const float* ptr1, const long str2[__VLA(D)], const float* ptr2); extern float md_scalar(unsigned int D, const long dim[__VLA(D)], const float* ptr1, const float* ptr2); extern void md_rss(unsigned int D, const long dims[__VLA(D)], unsigned int flags, float* dst, const float* src); extern void md_zrss(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* dst, const _Complex float* src); extern void md_zss(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* dst, const _Complex float* src); extern void md_zstd(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zstd2(unsigned int D, const long dims[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zvar(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zvar2(unsigned int D, const long dims[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zavg(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zavg2(unsigned int D, const long dims[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zwavg(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* optr, const _Complex float* iptr); extern void md_zwavg2(unsigned int D, const long dims[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr); extern void md_zwavg2_core1(unsigned int D, const long dims[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* weights); extern void md_zwavg2_core2(unsigned int D, const long dims[__VLA(D)], unsigned int flags, const long ostr[__VLA(D)], _Complex float* optr, const _Complex float* weights, const long istr[__VLA(D)], const _Complex float* iptr); extern float md_zrms(unsigned int D, const long dim[__VLA(D)], const _Complex float* in); extern float md_zrmse(unsigned int D, const long dim[__VLA(D)], const _Complex float* in1, const _Complex float* in2); extern float md_znrmse(unsigned int D, const long dim[__VLA(D)], const _Complex float* ref, const _Complex float* in); extern float md_znorme(unsigned int D, const long dim[__VLA(D)], const _Complex float* in1, const _Complex float* in2); extern float md_zrnorme(unsigned int D, const long dim[__VLA(D)], const _Complex float* ref, const _Complex float* in); extern void md_zdouble2float(unsigned int D, const long dims[__VLA(D)], _Complex float* dst, const _Complex double* src); extern void md_zfloat2double(unsigned int D, const long dims[__VLA(D)], _Complex double* dst, const _Complex float* src); extern void md_float2double(unsigned int D, const long dims[__VLA(D)], double* dst, const float* src); extern void md_double2float(unsigned int D, const long dims[__VLA(D)], float* dst, const double* src); extern void md_zdouble2float2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], _Complex float* dst, const long istr[__VLA(D)], const _Complex double* src); extern void md_zfloat2double2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], _Complex double* dst, const long istr[__VLA(D)], const _Complex float* src); extern void md_float2double2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], double* dst, const long istr[__VLA(D)], const float* src); extern void md_double2float2(unsigned int D, const long dims[__VLA(D)], const long ostr[__VLA(D)], float* dst, const long istr[__VLA(D)], const double* src); extern void md_zfill2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], _Complex float* ptr, _Complex float val); extern void md_zfill(unsigned int D, const long dim[__VLA(D)], _Complex float* ptr, _Complex float val); extern void md_zsmax2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr, float val); extern void md_zsmax(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr, float val); extern void md_smin2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr, float val); extern void md_smin(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr, float val); extern void md_smax2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], float* optr, const long istr[__VLA(D)], const float* iptr, float val); extern void md_smax(unsigned int D, const long dim[__VLA(D)], float* optr, const float* iptr, float val); extern void md_fdiff2(unsigned int D, const long dims[__VLA(D)], unsigned int d, const long ostr[__VLA(D)], float* out, const long istr[__VLA(D)], const float* in); extern void md_fdiff(unsigned int D, const long dims[__VLA(D)], unsigned int d, float* out, const float* in); extern void md_fdiff_backwards2(unsigned int D, const long dims[__VLA(D)], unsigned int d, const long ostr[__VLA(D)], float* out, const long istr[__VLA(D)], const float* in); extern void md_fdiff_backwards(unsigned int D, const long dims[__VLA(D)], unsigned int d, float* out, const float* in); extern void md_zfdiff2(unsigned int D, const long dims[__VLA(D)], unsigned int d, const long ostr[__VLA(D)], _Complex float* out, const long istr[__VLA(D)], const _Complex float* in); extern void md_zfdiff(unsigned int D, const long dims[__VLA(D)], unsigned int d, _Complex float* out, const _Complex float* in); extern void md_zfdiff_backwards2(unsigned int D, const long dims[__VLA(D)], unsigned int d, const long ostr[__VLA(D)], _Complex float* out, const long istr[__VLA(D)], const _Complex float* in); extern void md_zfdiff_backwards(unsigned int D, const long dims[__VLA(D)], unsigned int d, _Complex float* out, const _Complex float* in); extern void md_zfftmod(unsigned int D, const long dim[__VLA(D)], _Complex float* optr, const _Complex float* iptr, _Bool inv, double phase); extern void md_zfftmod2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], _Complex float* optr, const long istr[__VLA(D)], const _Complex float* iptr, _Bool inv, double phase); extern void md_zsum(unsigned int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* dst, const _Complex float* src); #include "misc/cppwrap.h" #endif bart-0.5.00/src/num/gpukrnls.cu000066400000000000000000000613241353046746100163270ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2017-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2015-2018 Jon Tamir * * * This file defines basic operations on vectors of floats/complex floats * for operations on the GPU. See the CPU version (vecops.c) for more * information. */ #include #include #include #include #include #include #include "num/gpukrnls.h" #if 1 // see Dara's src/calib/calibcu.cu for how to get // runtime info // limited by hardware to 1024 on most devices // should be a multiple of 32 (warp size) #define BLOCKSIZE 1024 static int blocksize(int N) { return BLOCKSIZE; } static int gridsize(int N) { return (N + BLOCKSIZE - 1) / BLOCKSIZE; } #else // http://stackoverflow.com/questions/5810447/cuda-block-and-grid-size-efficiencies #define WARPSIZE 32 #define MAXBLOCKS (16 * 8) // 16 multi processor times 8 blocks #define MIN(x, y) ((x < y) ? (x) : (y)) #define MAX(x, y) ((x > y) ? (x) : (y)) static int blocksize(int N) { int warps_total = (N + WARPSIZE - 1) / WARPSIZE; int warps_block = MAX(1, MIN(4, warps_total)); return WARPSIZE * warps_block; } static int gridsize(int N) { int warps_total = (N + WARPSIZE - 1) / WARPSIZE; int warps_block = MAX(1, MIN(4, warps_total)); return MIN(MAXBLOCKS, MAX(1, warps_total / warps_block)); } #endif __global__ void kern_float2double(int N, double* dst, const float* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = src[i]; } extern "C" void cuda_float2double(long N, double* dst, const float* src) { kern_float2double<<>>(N, dst, src); } __global__ void kern_double2float(int N, float* dst, const double* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = src[i]; } extern "C" void cuda_double2float(long N, float* dst, const double* src) { kern_double2float<<>>(N, dst, src); } __global__ void kern_xpay(int N, float beta, float* dst, const float* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = dst[i] * beta + src[i]; } extern "C" void cuda_xpay(long N, float beta, float* dst, const float* src) { kern_xpay<<>>(N, beta, dst, src); } __global__ void kern_axpbz(int N, float* dst, const float a1, const float* src1, const float a2, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = a1 * src1[i] + a2 * src2[i]; } extern "C" void cuda_axpbz(long N, float* dst, const float a1, const float* src1, const float a2, const float* src2) { kern_axpbz<<>>(N, dst, a1, src1, a2, src2); } __global__ void kern_smul(int N, float alpha, float* dst, const float* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = alpha * src[i]; } extern "C" void cuda_smul(long N, float alpha, float* dst, const float* src) { kern_smul<<>>(N, alpha, dst, src); } typedef void (*cuda_3op_f)(int N, float* dst, const float* src1, const float* src2); extern "C" void cuda_3op(cuda_3op_f krn, int N, float* dst, const float* src1, const float* src2) { krn<<>>(N, dst, src1, src2); } __global__ void kern_add(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = src1[i] + src2[i]; } extern "C" void cuda_add(long N, float* dst, const float* src1, const float* src2) { cuda_3op(kern_add, N, dst, src1, src2); } __global__ void kern_sub(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = src1[i] - src2[i]; } extern "C" void cuda_sub(long N, float* dst, const float* src1, const float* src2) { cuda_3op(kern_sub, N, dst, src1, src2); } __global__ void kern_mul(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = src1[i] * src2[i]; } extern "C" void cuda_mul(long N, float* dst, const float* src1, const float* src2) { cuda_3op(kern_mul, N, dst, src1, src2); } __global__ void kern_div(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = src1[i] / src2[i]; } extern "C" void cuda_div(long N, float* dst, const float* src1, const float* src2) { cuda_3op(kern_div, N, dst, src1, src2); } __global__ void kern_fmac(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] += src1[i] * src2[i]; } extern "C" void cuda_fmac(long N, float* dst, const float* src1, const float* src2) { cuda_3op(kern_fmac, N, dst, src1, src2); } __global__ void kern_fmac2(int N, double* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] += src1[i] * src2[i]; } extern "C" void cuda_fmac2(long N, double* dst, const float* src1, const float* src2) { kern_fmac2<<>>(N, dst, src1, src2); } __global__ void kern_zsmul(int N, cuFloatComplex val, cuFloatComplex* dst, const cuFloatComplex* src1) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCmulf(src1[i], val); } extern "C" void cuda_zsmul(long N, _Complex float alpha, _Complex float* dst, const _Complex float* src1) { kern_zsmul<<>>(N, make_cuFloatComplex(__real(alpha), __imag(alpha)), (cuFloatComplex*)dst, (const cuFloatComplex*)src1); } __global__ void kern_zmul(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCmulf(src1[i], src2[i]); } extern "C" void cuda_zmul(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zmul<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zdiv(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCdivf(src1[i], src2[i]); } extern "C" void cuda_zdiv(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zdiv<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zfmac(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCaddf(dst[i], cuCmulf(src1[i], src2[i])); } extern "C" void cuda_zfmac(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zfmac<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zfmac2(int N, cuDoubleComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCadd(dst[i], cuComplexFloatToDouble(cuCmulf(src1[i], src2[i]))); } extern "C" void cuda_zfmac2(long N, _Complex double* dst, const _Complex float* src1, const _Complex float* src2) { kern_zfmac2<<>>(N, (cuDoubleComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zmulc(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCmulf(src1[i], cuConjf(src2[i])); } extern "C" void cuda_zmulc(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zmulc<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zfmacc(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCaddf(dst[i], cuCmulf(src1[i], cuConjf(src2[i]))); } extern "C" void cuda_zfmacc(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zfmacc<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zfmacc2(int N, cuDoubleComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCadd(dst[i], cuComplexFloatToDouble(cuCmulf(src1[i], cuConjf(src2[i])))); } extern "C" void cuda_zfmacc2(long N, _Complex double* dst, const _Complex float* src1, const _Complex float* src2) { kern_zfmacc2<<>>(N, (cuDoubleComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_pow(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = powf(src1[i], src2[i]); } extern "C" void cuda_pow(long N, float* dst, const float* src1, const float* src2) { cuda_3op(kern_pow, N, dst, src1, src2); } __device__ cuDoubleComplex zexpD(cuDoubleComplex x) { double sc = exp(cuCreal(x)); double si; double co; sincos(cuCimag(x), &si, &co); return make_cuDoubleComplex(sc * co, sc * si); } __device__ cuFloatComplex zexp(cuFloatComplex x) { float sc = expf(cuCrealf(x)); float si; float co; sincosf(cuCimagf(x), &si, &co); return make_cuFloatComplex(sc * co, sc * si); } __device__ float zarg(cuFloatComplex x) { return atan2(cuCimagf(x), cuCrealf(x)); } __device__ float zabs(cuFloatComplex x) { return cuCabsf(x); } __device__ cuFloatComplex zlog(cuFloatComplex x) { return make_cuFloatComplex(log(cuCabsf(x)), zarg(x)); } // x^y = e^{y ln(x)} = e^{y __device__ cuFloatComplex zpow(cuFloatComplex x, cuFloatComplex y) { return zexp(cuCmulf(y, zlog(x))); } __global__ void kern_zpow(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = zpow(src1[i], src2[i]); } extern "C" void cuda_zpow(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zpow<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_sqrt(int N, float* dst, const float* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = sqrtf(fabs(src[i])); } extern "C" void cuda_sqrt(long N, float* dst, const float* src) { kern_sqrt<<>>(N, dst, src); } __global__ void kern_zconj(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuConjf(src[i]); } extern "C" void cuda_zconj(long N, _Complex float* dst, const _Complex float* src) { kern_zconj<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_zcmp(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = make_cuFloatComplex(((cuCrealf(src1[i]) == cuCrealf(src2[i])) && (cuCimagf(src1[i]) == cuCimagf(src2[i]))) ? 1. : 0, 0.); } extern "C" void cuda_zcmp(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zcmp<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_zdiv_reg(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2, cuFloatComplex lambda) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = cuCdivf(src1[i], cuCaddf(src2[i], lambda)); } extern "C" void cuda_zdiv_reg(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2, _Complex float lambda) { kern_zdiv_reg<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2, make_cuFloatComplex(__real(lambda), __imag(lambda))); } __global__ void kern_zphsr(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { float abs = cuCabsf(src[i]); // moved out, otherwise it triggers a compiler error in nvcc dst[i] = (0. == abs) ? make_cuFloatComplex(1., 0.) : (cuCdivf(src[i], make_cuFloatComplex(abs, 0.))); } } extern "C" void cuda_zphsr(long N, _Complex float* dst, const _Complex float* src) { kern_zphsr<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_zexp(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = zexp(src[i]); } extern "C" void cuda_zexp(long N, _Complex float* dst, const _Complex float* src) { kern_zexp<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_zexpj(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { float abs = cuCabsf(src[i]); // moved out, otherwise it triggers a compiler error in nvcc dst[i] = zexp(make_cuFloatComplex(0., abs)); } } extern "C" void cuda_zexpj(long N, _Complex float* dst, const _Complex float* src) { kern_zexpj<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_zarg(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = make_cuFloatComplex(zarg(src[i]), 0.); } extern "C" void cuda_zarg(long N, _Complex float* dst, const _Complex float* src) { kern_zarg<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_zabs(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = make_cuFloatComplex(zabs(src[i]), 0.); } extern "C" void cuda_zabs(long N, _Complex float* dst, const _Complex float* src) { kern_zabs<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } /** * (GPU) Step (1) of soft thesholding, y = ST(x, lambda). * Only computes the residual, resid = MAX( (abs(x) - lambda)/abs(x)), 0 ) * * @param N number of elements * @param lambda threshold parameter * @param d pointer to destination, resid * @param x pointer to input */ __global__ void kern_zsoftthresh_half(int N, float lambda, cuFloatComplex* d, const cuFloatComplex* x) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { float norm = cuCabsf(x[i]); float red = norm - lambda; //d[i] = (red > 0.) ? (cuCmulf(make_cuFloatComplex(red / norm, 0.), x[i])) : make_cuFloatComplex(0., 0.); d[i] = (red > 0.) ? make_cuFloatComplex(red / norm, 0.) : make_cuFloatComplex(0., 0.); } } extern "C" void cuda_zsoftthresh_half(long N, float lambda, _Complex float* d, const _Complex float* x) { kern_zsoftthresh_half<<>>(N, lambda, (cuFloatComplex*)d, (const cuFloatComplex*)x); } __global__ void kern_zsoftthresh(int N, float lambda, cuFloatComplex* d, const cuFloatComplex* x) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { float norm = cuCabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (cuCmulf(make_cuFloatComplex(red / norm, 0.), x[i])) : make_cuFloatComplex(0., 0.); } } extern "C" void cuda_zsoftthresh(long N, float lambda, _Complex float* d, const _Complex float* x) { kern_zsoftthresh<<>>(N, lambda, (cuFloatComplex*)d, (const cuFloatComplex*)x); } __global__ void kern_softthresh_half(int N, float lambda, float* d, const float* x) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { float norm = fabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (red / norm) : 0.; } } extern "C" void cuda_softthresh_half(long N, float lambda, float* d, const float* x) { kern_softthresh_half<<>>(N, lambda, d, x); } __global__ void kern_softthresh(int N, float lambda, float* d, const float* x) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { float norm = fabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (red / norm * x[i]) : 0.; } } extern "C" void cuda_softthresh(long N, float lambda, float* d, const float* x) { kern_softthresh<<>>(N, lambda, d, x); } __global__ void kern_zreal(int N, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = make_cuFloatComplex(cuCrealf(src[i]), 0.); } extern "C" void cuda_zreal(long N, _Complex float* dst, const _Complex float* src) { kern_zreal<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_zle(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = make_cuFloatComplex((cuCrealf(src1[i]) <= cuCrealf(src2[i])), 0.); } extern "C" void cuda_zle(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zle<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } __global__ void kern_le(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = (src1[i] <= src2[i]); } extern "C" void cuda_le(long N, float* dst, const float* src1, const float* src2) { kern_le<<>>(N, dst, src1, src2); } __device__ cuFloatComplex cuDouble2Float(cuDoubleComplex x) { return make_cuFloatComplex(cuCreal(x), cuCimag(x)); } __device__ cuDoubleComplex cuFloat2Double(cuFloatComplex x) { return make_cuDoubleComplex(cuCrealf(x), cuCimagf(x)); } // identical copy in num/fft.c __device__ double fftmod_phase(long length, int j) { long center1 = length / 2; double shift = (double)center1 / (double)length; return ((double)j - (double)center1 / 2.) * shift; } __device__ cuDoubleComplex fftmod_phase2(long n, int j, bool inv, double phase) { phase += fftmod_phase(n, j); double rem = phase - floor(phase); double sgn = inv ? -1. : 1.; #if 1 if (rem == 0.) return make_cuDoubleComplex(1., 0.); if (rem == 0.5) return make_cuDoubleComplex(-1., 0.); if (rem == 0.25) return make_cuDoubleComplex(0., sgn); if (rem == 0.75) return make_cuDoubleComplex(0., -sgn); #endif return zexpD(make_cuDoubleComplex(0., M_PI * 2. * sgn * rem)); } __global__ void kern_zfftmod(int N, cuFloatComplex* dst, const cuFloatComplex* src, unsigned int n, _Bool inv, double phase) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) for (int j = 0; j < n; j++) dst[i * n + j] = cuDouble2Float(cuCmul(fftmod_phase2(n, j, inv, phase), cuFloat2Double(src[i * n + j]))); } extern "C" void cuda_zfftmod(long N, _Complex float* dst, const _Complex float* src, unsigned int n, _Bool inv, double phase) { kern_zfftmod<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src, n, inv, phase); } __global__ void kern_zmax(int N, cuFloatComplex* dst, const cuFloatComplex* src1, const cuFloatComplex* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = (cuCrealf(src1[i]) > cuCrealf(src2[i])) ? src1[i] : src2[i]; } extern "C" void cuda_zmax(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2) { kern_zmax<<>>(N, (cuFloatComplex*)dst, (const cuFloatComplex*)src1, (const cuFloatComplex*)src2); } #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) __global__ void kern_smax(int N, float val, float* dst, const float* src1) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = MAX(src1[i], val); } extern "C" void cuda_smax(long N, float val, float* dst, const float* src1) { kern_smax<<>>(N, val, dst, src1); } __global__ void kern_max(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = MAX(src1[i], src2[i]); } extern "C" void cuda_max(long N, float* dst, const float* src1, const float* src2) { kern_max<<>>(N, dst, src1, src2); } __global__ void kern_min(int N, float* dst, const float* src1, const float* src2) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) dst[i] = MIN(src1[i], src2[i]); } extern "C" void cuda_min(long N, float* dst, const float* src1, const float* src2) { kern_min<<>>(N, dst, src1, src2); } __global__ void kern_zsmax(int N, float val, cuFloatComplex* dst, const cuFloatComplex* src) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; for (int i = start; i < N; i += stride) { dst[i].x = MAX(src[i].x, val); dst[i].y = 0.0; } } extern "C" void cuda_zsmax(long N, float alpha, _Complex float* dst, const _Complex float* src) { kern_zsmax<<>>(N, alpha, (cuFloatComplex*)dst, (const cuFloatComplex*)src); } __global__ void kern_reduce_zsum(int N, cuFloatComplex* dst) { int start = threadIdx.x + blockDim.x * blockIdx.x; int stride = blockDim.x * gridDim.x; cuFloatComplex sum = make_cuFloatComplex(0., 0.); for (int i = start; i < N; i += stride) sum = cuCaddf(sum, dst[i]); if (start < N) dst[start] = sum; } extern "C" void cuda_zsum(long N, _Complex float* dst) { int B = blocksize(N); while (N > 1) { kern_reduce_zsum<<<1, B>>>(N, (cuFloatComplex*)dst); N = MIN(B, N); B /= 32; } } bart-0.5.00/src/num/gpukrnls.h000066400000000000000000000103131353046746100161370ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus extern "C" { #endif extern void cuda_float2double(long size, double* dst, const float* src); extern void cuda_double2float(long size, float* dst, const double* src); extern void cuda_sxpay(long size, float* y, float alpha, const float* src); extern void cuda_xpay(long N, float beta, float* dst, const float* src); extern void cuda_axpbz(long N, float* dst, const float a, const float* x, const float b, const float* z); extern void cuda_smul(long N, float alpha, float* dst, const float* src); extern void cuda_mul(long N, float* dst, const float* src1, const float* src2); extern void cuda_div(long N, float* dst, const float* src1, const float* src2); extern void cuda_add(long N, float* dst, const float* src1, const float* src2); extern void cuda_sub(long N, float* dst, const float* src1, const float* src2); extern void cuda_fmac(long N, float* dst, const float* src1, const float* src2); extern void cuda_fmac2(long N, double* dst, const float* src1, const float* src2); extern void cuda_zsmul(long N, _Complex float alpha, _Complex float* dst, const _Complex float* src1); extern void cuda_zmul(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zdiv(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zfmac(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zfmac2(long N, _Complex double* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zmulc(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zfmacc(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zfmacc2(long N, _Complex double* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_pow(long N, float* dst, const float* src1, const float* src2); extern void cuda_zpow(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_sqrt(long N, float* dst, const float* src); extern void cuda_zconj(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zphsr(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zexpj(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zexp(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zarg(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zabs(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zsoftthresh_half(long N, float lambda, _Complex float* d, const _Complex float* x); extern void cuda_zsoftthresh(long N, float lambda, _Complex float* d, const _Complex float* x); extern void cuda_softthresh_half(long N, float lambda, float* d, const float* x); extern void cuda_softthresh(long N, float lambda, float* d, const float* x); extern void cuda_zreal(long N, _Complex float* dst, const _Complex float* src); extern void cuda_zcmp(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zdiv_reg(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2, _Complex float lambda); extern void cuda_le(long N, float* dst, const float* src1, const float* src2); extern void cuda_zfftmod(long N, _Complex float* dst, const _Complex float* src, unsigned int n, _Bool inv, double phase); extern void cuda_zmax(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_zle(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); extern void cuda_smax(long N, float val, float* dst, const float* src1); extern void cuda_max(long N, float* dst, const float* src1, const float* src2); extern void cuda_min(long N, float* dst, const float* src1, const float* src2); extern void cuda_zsum(long N, _Complex float* dst); extern void cuda_zsmax(long N, float alpha, _Complex float* dst, const _Complex float* src); #ifdef __cplusplus } #endif bart-0.5.00/src/num/gpuops.c000066400000000000000000000225251353046746100156120ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2014. Joseph Y Cheng. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * 2014 Joseph Y Cheng * 2015-2018 Jon Tamir * * * CUDA support functions. The file exports gpu_ops of type struct vec_ops * for basic operations on single-precision floating pointer vectors defined * in gpukrnls.cu. See vecops.c for the CPU version. */ #ifdef USE_CUDA #include #include #include #include #include #include #include "num/vecops.h" #include "num/gpuops.h" #include "num/gpukrnls.h" #include "num/mem.h" #include "misc/misc.h" #include "misc/debug.h" #include "gpuops.h" #define MiBYTE (1024*1024) static void cuda_error(int line, cudaError_t code) { const char *err_str = cudaGetErrorString(code); error("cuda error: %d %s \n", line, err_str); } #define CUDA_ERROR(x) ({ cudaError_t errval = (x); if (cudaSuccess != errval) cuda_error(__LINE__, errval); }) // Print free and used memory on GPU. void print_cuda_meminfo(void) { size_t byte_tot; size_t byte_free; cudaError_t cuda_status = cudaMemGetInfo(&byte_free, &byte_tot); if (cuda_status != cudaSuccess) error("ERROR: cudaMemGetInfo failed. %s\n", cudaGetErrorString(cuda_status)); double dbyte_tot = (double)byte_tot; double dbyte_free = (double)byte_free; double dbyte_used = dbyte_tot - dbyte_free; debug_printf(DP_INFO , "GPU memory usage: used = %.4f MiB, free = %.4f MiB, total = %.4f MiB\n", dbyte_used/MiBYTE, dbyte_free/MiBYTE, dbyte_tot/MiBYTE); } int cuda_devices(void) { int count; CUDA_ERROR(cudaGetDeviceCount(&count)); return count; } static __thread int last_init = -1; void cuda_p2p_table(int n, bool table[n][n]) { assert(n == cuda_devices()); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { int r; CUDA_ERROR(cudaDeviceCanAccessPeer(&r, i, j)); table[i][j] = (1 == r); } } } void cuda_p2p(int a, int b) { int dev; CUDA_ERROR(cudaGetDevice(&dev)); CUDA_ERROR(cudaSetDevice(a)); CUDA_ERROR(cudaDeviceEnablePeerAccess(b, 0)); CUDA_ERROR(cudaSetDevice(dev)); } void cuda_init(int device) { last_init = device; CUDA_ERROR(cudaSetDevice(device)); } int cuda_init_memopt(void) { int num_devices = cuda_devices(); int device; int max_device = 0; if (num_devices > 1) { size_t mem_max = 0; size_t mem_free; size_t mem_total; for (device = 0; device < num_devices; device++) { cuda_init(device); CUDA_ERROR(cudaMemGetInfo(&mem_free, &mem_total)); //printf(" device (%d): %d\n", device, mem_available); if (mem_max < mem_free) { mem_max = mem_free; max_device = device; } } //printf(" max device: %d\n", max_device); CUDA_ERROR(cudaSetDevice(max_device)); // FIXME: we should set last_init } return max_device; } bool cuda_memcache = true; void cuda_memcache_off(void) { assert(-1 == last_init); cuda_memcache = false; } void cuda_clear(long size, void* dst) { // printf("CLEAR %x %ld\n", dst, size); CUDA_ERROR(cudaMemset(dst, 0, size)); } static void cuda_float_clear(long size, float* dst) { cuda_clear(size * sizeof(float), (void*)dst); } void cuda_memcpy(long size, void* dst, const void* src) { // printf("COPY %x %x %ld\n", dst, src, size); CUDA_ERROR(cudaMemcpy(dst, src, size, cudaMemcpyDefault)); } void cuda_memcpy_strided(const long dims[2], long ostr, void* dst, long istr, const void* src) { CUDA_ERROR(cudaMemcpy2D(dst, ostr, src, istr, dims[0], dims[1], cudaMemcpyDefault)); } static void cuda_float_copy(long size, float* dst, const float* src) { cuda_memcpy(size * sizeof(float), (void*)dst, (const void*)src); } static void cuda_free_wrapper(const void* ptr) { CUDA_ERROR(cudaFree((void*)ptr)); } void cuda_memcache_clear(void) { if (!cuda_memcache) return; memcache_clear(last_init, cuda_free_wrapper); } void cuda_exit(void) { cuda_memcache_clear(); CUDA_ERROR(cudaDeviceReset()); } #if 0 // We still don use this because it is slow. Why? Nivida, why? static bool cuda_cuda_ondevice(const void* ptr) { if (NULL == ptr) return false; struct cudaPointerAttributes attr; if (cudaSuccess != (cudaPointerGetAttributes(&attr, ptr))) { /* The secret trick to make this work for arbitrary pointers is to clear the error using cudaGetLastError. See end of: http://www.alexstjohn.com/WP/2014/04/28/cuda-6-0-first-look/ */ cudaGetLastError(); return false; } return (cudaMemoryTypeDevice == attr.memoryType); } #endif bool cuda_ondevice(const void* ptr) { return mem_ondevice(ptr); } bool cuda_accessible(const void* ptr) { #if 1 return mem_device_accessible(ptr); #else struct cudaPointerAttributes attr; //CUDA_ERROR(cudaPointerGetAttributes(&attr, ptr)); if (cudaSuccess != (cudaPointerGetAttributes(&attr, ptr))) return false; return true; #endif } void cuda_free(void* ptr) { mem_device_free(ptr, cuda_free_wrapper); } bool cuda_global_memory = false; void cuda_use_global_memory(void) { cuda_global_memory = true; } static void* cuda_malloc_wrapper(size_t size) { void* ptr; if (cuda_global_memory) { CUDA_ERROR(cudaMallocManaged(&ptr, size, cudaMemAttachGlobal)); } else { CUDA_ERROR(cudaMalloc(&ptr, size)); } return ptr; } void* cuda_malloc(long size) { return mem_device_malloc(last_init, size, cuda_malloc_wrapper); } #if 0 void* cuda_hostalloc(long N) { void* ptr; if (cudaSuccess != cudaHostAlloc(&ptr, N, cudaHostAllocDefault)) error("abort"); insert(ptr, N, false); return ptr; } void cuda_hostfree(void* ptr) { struct cuda_mem_s* nptr = search(ptr, true); assert(nptr->ptr == ptr); assert(!nptr->device); xfree(nptr); cudaFreeHost(ptr); } #endif static float* cuda_float_malloc(long size) { return (float*)cuda_malloc(size * sizeof(float)); } static void cuda_float_free(float* x) { cuda_free((void*)x); } static double cuda_sdot(long size, const float* src1, const float* src2) { assert(cuda_ondevice(src1)); assert(cuda_ondevice(src2)); // printf("SDOT %x %x %ld\n", src1, src2, size); return cublasSdot(size, src1, 1, src2, 1); } static double cuda_norm(long size, const float* src1) { #if 1 // cublasSnrm2 produces NaN in some situations // e.g. nlinv -g -i8 utests/data/und2x2 o // git rev: ab28a9a953a80d243511640b23501f964a585349 // printf("cublas: %f\n", cublasSnrm2(size, src1, 1)); // printf("GPU norm (sdot: %f)\n", sqrt(cuda_sdot(size, src1, src1))); return sqrt(cuda_sdot(size, src1, src1)); #else return cublasSnrm2(size, src1, 1); #endif } static double cuda_asum(long size, const float* src) { return cublasSasum(size, src, 1); } static void cuda_saxpy(long size, float* y, float alpha, const float* src) { // printf("SAXPY %x %x %ld\n", y, src, size); cublasSaxpy(size, alpha, src, 1, y, 1); } static void cuda_swap(long size, float* a, float* b) { cublasSswap(size, a, 1, b, 1); } const struct vec_ops gpu_ops = { .float2double = cuda_float2double, .double2float = cuda_double2float, .dot = cuda_sdot, .asum = cuda_asum, .zsum = cuda_zsum, .zl1norm = NULL, .add = cuda_add, .sub = cuda_sub, .mul = cuda_mul, .div = cuda_div, .fmac = cuda_fmac, .fmac2 = cuda_fmac2, .smul = cuda_smul, .axpy = cuda_saxpy, .pow = cuda_pow, .sqrt = cuda_sqrt, .le = cuda_le, .zsmul = cuda_zsmul, .zsmax = cuda_zsmax, .zmul = cuda_zmul, .zdiv = cuda_zdiv, .zfmac = cuda_zfmac, .zfmac2 = cuda_zfmac2, .zmulc = cuda_zmulc, .zfmacc = cuda_zfmacc, .zfmacc2 = cuda_zfmacc2, .zpow = cuda_zpow, .zphsr = cuda_zphsr, .zconj = cuda_zconj, .zexpj = cuda_zexpj, .zexp = cuda_zexp, .zarg = cuda_zarg, .zabs = cuda_zabs, .zcmp = cuda_zcmp, .zdiv_reg = cuda_zdiv_reg, .zfftmod = cuda_zfftmod, .zmax = cuda_zmax, .zle = cuda_zle, .smax = cuda_smax, .max = cuda_max, .min = cuda_min, .zsoftthresh = cuda_zsoftthresh, .zsoftthresh_half = cuda_zsoftthresh_half, .softthresh = cuda_softthresh, .softthresh_half = cuda_softthresh_half, .zhardthresh = NULL, }; // defined in iter/vec.h struct vec_iter_s { float* (*allocate)(long N); void (*del)(float* x); void (*clear)(long N, float* x); void (*copy)(long N, float* a, const float* x); void (*swap)(long N, float* a, float* x); double (*norm)(long N, const float* x); double (*dot)(long N, const float* x, const float* y); void (*sub)(long N, float* a, const float* x, const float* y); void (*add)(long N, float* a, const float* x, const float* y); void (*smul)(long N, float alpha, float* a, const float* x); void (*xpay)(long N, float alpha, float* a, const float* x); void (*axpy)(long N, float* a, float alpha, const float* x); void (*axpbz)(long N, float* out, const float a, const float* x, const float b, const float* z); void (*zmul)(long N, complex float* dst, const complex float* src1, const complex float* src2); }; extern const struct vec_iter_s gpu_iter_ops; const struct vec_iter_s gpu_iter_ops = { .allocate = cuda_float_malloc, .del = cuda_float_free, .clear = cuda_float_clear, .copy = cuda_float_copy, .dot = cuda_sdot, .norm = cuda_norm, .axpy = cuda_saxpy, .xpay = cuda_xpay, .axpbz = cuda_axpbz, .smul = cuda_smul, .add = cuda_add, .sub = cuda_sub, .swap = cuda_swap, .zmul = cuda_zmul, }; #endif bart-0.5.00/src/num/gpuops.h000066400000000000000000000021361353046746100156130ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus extern "C" { #endif extern const struct vec_ops gpu_ops; extern _Bool cuda_ondevice(const void* ptr); extern _Bool cuda_accessible(const void* ptr); extern void cuda_clear(long size, void* ptr); extern void cuda_memcpy(long size, void* dst, const void* src); extern void cuda_hostfree(void*); extern void* cuda_hostalloc(long N); extern void* cuda_malloc(long N); extern void cuda_memcpy_strided(const long dims[2], long ostr, void* dst, long istr, const void* src); extern void cuda_free(void*); extern void cuda_init(int device); extern int cuda_init_memopt(void); extern void cuda_p2p_table(int n, _Bool table[n][n]); extern void cuda_p2p(int a, int b); extern void cuda_exit(void); extern int cuda_devices(void); extern void cuda_memcache_off(void); extern void cuda_memcache_clear(void); extern void cuda_use_global_memory(void); extern void print_cuda_meminfo(void); #ifdef __cplusplus } #endif bart-0.5.00/src/num/init.c000066400000000000000000000043321353046746100152340ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2018 Martin Uecker * * * Initialization routines. */ #define _GNU_SOURCE #include #include #include #ifdef _OPENMP #include #endif #include "misc/debug.h" #include "misc/misc.h" #include "num/fft.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #ifdef USE_CULA #include #endif #include "init.h" extern unsigned long num_chunk_size; // num/optimize.c void num_init(void) { #ifdef __linux__ // feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW); #endif #if 0 // set stack limit if (-1 == setrlimit(RLIMIT_STACK, &(struct rlimit){ 500000000, 500000000 })) debug_printf(DP_WARN, "error setting stack size\n"); // FIXME: should also set openmp stack size #endif #ifdef _OPENMP int p = omp_get_num_procs(); if (NULL == getenv("OMP_NUM_THREADS")) omp_set_num_threads(p); p = omp_get_max_threads(); // omp_set_nested(1); #else int p = 2; #endif #ifdef FFTWTHREADS fft_set_num_threads(p); #endif const char* chunk_str; if (NULL != (chunk_str = getenv("BART_PARALLEL_CHUNK_SIZE"))) { long chunk_size = strtoul(chunk_str, NULL, 10); if (0 < chunk_size) { num_chunk_size = chunk_size; } else { debug_printf(DP_WARN, "invalid chunk size\n"); } } } void num_init_gpu(void) { num_init(); // don't call cuda_init so that GPU can get assigned by driver #ifdef USE_CULA culaInitialize(); #endif } void num_init_gpu_device(int device) { num_init(); #ifdef USE_CUDA cuda_init(device); #else (void)device; error("BART compiled without GPU support.\n"); #endif #ifdef USE_CULA culaInitialize(); #endif } void num_init_gpu_memopt(void) { num_init(); #ifdef USE_CUDA cuda_init_memopt(); #else error("BART compiled without GPU support.\n"); #endif #ifdef USE_CULA culaInitialize(); #endif } void num_set_num_threads(int n) { #ifdef _OPENMP omp_set_num_threads(n); #endif #ifdef FFTWTHREADS fft_set_num_threads(n); #endif } bart-0.5.00/src/num/init.h000066400000000000000000000007531353046746100152440ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ extern void num_init(void); extern void num_init_gpu(void); /** * selects the GPU with the maximum available memory * (if there are more than one on the system) */ extern void num_init_gpu_memopt(void); extern void num_init_gpu_device(int device); extern void num_set_num_threads(int n); bart-0.5.00/src/num/iovec.c000066400000000000000000000037001353046746100153740ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker */ #include #include "misc/misc.h" #include "misc/debug.h" #include "num/multind.h" #include "num/flpmath.h" #include "iovec.h" #if 1 void debug_print_iovec(int level, const struct iovec_s* vec) { debug_printf(level, "iovec:\n"); debug_printf(level, " N = %d\n", vec->N); debug_printf(level, " dims = \t"); debug_print_dims(level, vec->N, vec->dims); debug_printf(level, " strs = \t"); debug_print_dims(level, vec->N, vec->strs); } #endif void iovec_init2(struct iovec_s* n, unsigned int N, const long dims[N], const long strs[N], size_t size) { n->N = N; PTR_ALLOC(long[N], ndims); memcpy(*ndims, dims, N * sizeof(long)); n->dims = *PTR_PASS(ndims); PTR_ALLOC(long[N], nstrs); memcpy(*nstrs, strs, N * sizeof(long)); n->strs = *PTR_PASS(nstrs); n->size = size; } const struct iovec_s* iovec_create2(unsigned int N, const long dims[N], const long strs[N], size_t size) { PTR_ALLOC(struct iovec_s, n); iovec_init2(n, N, dims, strs, size); return PTR_PASS(n); } const struct iovec_s* iovec_create(unsigned int N, const long dims[N], size_t size) { long strs[N]; md_calc_strides(N, strs, dims, size); return iovec_create2(N, dims, strs, size); } void iovec_destroy(const struct iovec_s* x) { xfree(x->dims); xfree(x->strs); } void iovec_free(const struct iovec_s* x) { iovec_destroy(x); xfree(x); } bool iovec_check(const struct iovec_s* iov, unsigned int N, const long dims[N], const long strs[N]) { bool ok = true; debug_print_dims(DP_DEBUG4, N, dims); debug_print_dims(DP_DEBUG4, iov->N, iov->dims); if (N != iov->N) return false; for (unsigned int i = 0; i < N; i++) { ok &= (dims[i] == iov->dims[i]); ok &= (strs[i] == iov->strs[i]); } return ok; } bart-0.5.00/src/num/iovec.h000066400000000000000000000021701353046746100154010ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker */ #include #include #include "misc/cppwrap.h" struct iovec_s { unsigned int N; const long* dims; const long* strs; size_t size; }; extern const struct iovec_s* iovec_create(unsigned int N, const long dims[__VLA(N)], size_t size); extern const struct iovec_s* iovec_create2(unsigned int N, const long dims[__VLA(N)], const long strs[__VLA(N)], size_t size); extern void iovec_free(const struct iovec_s* x); extern bool iovec_check(const struct iovec_s* iov, unsigned int N, const long dims[__VLA(N)], const long strs[__VLA(N)]); // in-place initialization and deconstruction extern void iovec_init2(struct iovec_s* n, unsigned int N, const long dims[__VLA(N)], const long strs[__VLA(N)], size_t size); extern void iovec_destroy(const struct iovec_s* x); extern void debug_print_iovec(int level, const struct iovec_s* vec); #include "misc/cppwrap.h" bart-0.5.00/src/num/lapack.c000066400000000000000000000046521353046746100155310ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker * 2017 Jon Tamir */ #include "misc/misc.h" #ifndef NOLAPACKE #include #else #include "lapacke/lapacke.h" #endif #include "lapack.h" #define LAPACKE(x, ...) \ if (0 != LAPACKE_##x(LAPACK_COL_MAJOR, __VA_ARGS__)) \ error("LAPACK: " # x " failed."); /* ATTENTION: blas and lapack use column-major matrices * while native C uses row-major. All matrices are * transposed to what one would expect. * * LAPACK svd destroys its input matrix **/ void lapack_eig(long N, float eigenval[N], complex float matrix[N][N]) { LAPACKE(cheev, 'V', 'U', N, &matrix[0][0], N, eigenval); } void lapack_svd(long M, long N, complex float U[M][M], complex float VH[N][N], float S[(N > M) ? M : N], complex float A[N][M]) { LAPACKE(cgesdd, 'A', M, N, &A[0][0], M, S, &U[0][0], M, &VH[0][0], N); } void lapack_svd_econ(long M, long N, complex float U[M][(N > M) ? M : N], complex float VH[(N > M) ? M : N][N], float S[(N > M) ? M : N], complex float A[N][M]) { PTR_ALLOC(float[MIN(M, N) - 1], superb); LAPACKE(cgesvd, 'S', 'S', M, N, &A[0][0], M, S, &U[0][0], M, &VH[0][0], MIN(M, N), *superb); PTR_FREE(superb); } void lapack_eig_double(long N, double eigenval[N], complex double matrix[N][N]) { LAPACKE(zheev, 'V', 'U', N, &matrix[0][0], N, eigenval); } void lapack_svd_double(long M, long N, complex double U[M][M], complex double VH[N][N], double S[(N > M) ? M : N], complex double A[N][M]) { LAPACKE(zgesdd, 'A', M, N, &A[0][0], M, S, &U[0][0], M, &VH[0][0], N); } static void lapack_cholesky_UL(long N, char UL, complex float A[N][N]) { LAPACKE(cpotrf, UL, N, &A[0][0], N); } void lapack_cholesky(long N, complex float A[N][N]) { lapack_cholesky_UL(N, 'U', A); } void lapack_cholesky_lower(long N, complex float A[N][N]) { lapack_cholesky_UL(N, 'L', A); } static void lapack_trimat_inverse_UL(long N, char UL, complex float A[N][N]) { LAPACKE(ctrtri, UL, 'N', N, &A[0][0], N); } void lapack_trimat_inverse(long N, complex float A[N][N]) { lapack_trimat_inverse_UL(N, 'U', A); } void lapack_trimat_inverse_lower(long N, complex float A[N][N]) { lapack_trimat_inverse_UL(N, 'L', A); } bart-0.5.00/src/num/lapack.h000066400000000000000000000025021353046746100155260ustar00rootroot00000000000000/* Copyright 2013-2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #ifdef __cplusplus #error This file does not support C++ #endif extern void lapack_eig(long N, float eigenval[N], complex float matrix[N][N]); extern void lapack_svd(long M, long N, complex float U[M][M], complex float VH[N][N], float S[(N > M) ? M : N], complex float A[N][M]); extern void lapack_svd_econ(long M, long N, complex float U[M][(N > M) ? M : N], complex float VH[(N > M) ? M : N][N], float S[(N > M) ? M : N], complex float A[N][M]); extern void lapack_eig_double(long N, double eigenval[N], complex double matrix[N][N]); extern void lapack_svd_double(long M, long N, complex double U[M][M], complex double VH[N][N], double S[(N > M) ? M : N], complex double A[N][M]); extern void lapack_matrix_multiply(long M, long N, long K, complex float C[M][N], const complex float A[M][K], const complex float B[K][N]); extern void lapack_cholesky(long N, complex float A[N][N]); extern void lapack_cholesky_lower(long N, complex float A[N][N]); extern void lapack_trimat_inverse(long N, complex float A[N][N]); extern void lapack_trimat_inverse_lower(long N, complex float A[N][N]); bart-0.5.00/src/num/linalg.c000066400000000000000000000300741353046746100155410ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * 2013 Dara Bahri * * * Simple linear algebra functions. */ #include #include #include #if 1 // #define MAT_USE_LAPACK #define DOUBLE_ACC #endif #include "misc/misc.h" #ifdef MAT_USE_LAPACK #include "num/blas.h" #include "num/lapack.h" #endif #include "num/rand.h" #include "linalg.h" #ifdef DOUBLE_ACC typedef complex double cfl_acu_t; typedef double fl_acu_t; #else typedef complex float cfl_acu_t; typedef float fl_acu_t; #endif void mat_identity(int A, int B, complex float x[A][B]) { for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) x[i][j] = (i == j) ? 1. : 0.; } void mat_zero(int A, int B, complex float m[A][B]) { for (int a = 0; a < A; a++) for (int b = 0; b < B; b++) m[a][b] = 0.; } void mat_gaussian(int A, int B, complex float x[A][B]) { for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) x[i][j] = gaussian_rand(); } // add constant to vector void vec_sadd(long D, complex float alpha, complex float dst[D], const complex float src[D]) { // #pragma omp parallel for for (long i = 0; i < D; i++) dst[i] = alpha + src[i]; } complex float vec_mean(long D, const complex float src[D]) { cfl_acu_t val = 0; for (long i = 0; i < D; i++) val += src[i]; return val / D; } void (mat_add)(int A, int B, complex float x[A][B], const complex float y[A][B], const complex float z[A][B]) { for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) x[i][j] = y[i][j] + z[i][j]; } void (mat_muladd)(int A, int B, int C, complex float x[MVLA(A)][C], const complex float y[MVLA(A)][B], const complex float z[MVLA(B)][C]) { #ifdef MAT_USE_LAPACK complex float tmp[A][C]; mat_mul(A, B, C, tmp, y, z); mat_add(A, C, x, x, tmp); #else for (int i = 0; i < A; i++) { for (int j = 0; j < C; j++) { cfl_acu_t tmp = 0.; for (int k = 0; k < B; k++) tmp += y[i][k] * z[k][j]; x[i][j] += tmp; } } #endif } void (mat_mul)(int A, int B, int C, complex float x[A][C], const complex float y[A][B], const complex float z[B][C]) { #ifdef MAT_USE_LAPACK blas_matrix_multiply(C, A, B, x, z, y); #else for (int i = 0; i < A; i++) { for (int j = 0; j < C; j++) { cfl_acu_t tmp = 0.; for (int k = 0; k < B; k++) tmp += y[i][k] * z[k][j]; x[i][j] = tmp; } } #endif } bool (mat_inverse)(unsigned int N, complex float out[N][N], const complex float in[N][N]) { #ifdef MAT_USE_LAPACK // return blas_matrix_inverse(N, out, in); UNUSED(in); UNUSED(out); assert(0); #else // ATTENTION: slow and inaccurate complex float tmp[2 * N][N]; mat_transpose(N, N, tmp, in); mat_identity(N, N, tmp + N); complex float tmp2[N][2 * N]; mat_transpose(2 * N, N, tmp2, tmp); for (unsigned int i = 0; i < N; i++) { complex float diag = tmp2[i][i]; if (0. == diag) return false; for (unsigned int j = 0; j < 2 * N; j++) tmp2[i][j] /= diag; for (unsigned int j = 0; j < N; j++) { if (i != j) vec_saxpy(2 * N, tmp2[j], -tmp2[j][i], tmp2[i]); } } mat_transpose(N, 2 * N, tmp, tmp2); mat_transpose(N, N, out, tmp + N); return true; #endif } void mat_pinv(unsigned int A, unsigned int B, complex float out[B][A], const complex float in[A][B]) { if (A == B) { mat_inverse(A, out, in); return; } assert(B < A); complex float adj[B][A]; mat_adjoint(A, B, adj, in); complex float prod[B][B]; mat_mul(B, A, B, prod, adj, in); complex float inv[B][B]; mat_inverse(B, inv, prod); mat_mul(B, B, A, out, inv, adj); } void (mat_kron)(unsigned int A, unsigned int B, unsigned int C, unsigned int D, complex float out[A * C][B * D], const complex float in1[A][B], const complex float in2[C][D]) { for (unsigned int a = 0; a < A; a++) for (unsigned int b = 0; b < B; b++) for (unsigned int c = 0; c < C; c++) for (unsigned int d = 0; d < D; d++) out[a + c * A][b + d * B] = in1[a][b] * in2[c][d]; } void (mat_vecmul)(unsigned int A, unsigned int B, complex float out[A], const complex float mat[A][B], const complex float in[B]) { for (unsigned int a = 0; a < A; a++) { cfl_acu_t tmp = 0.; for (unsigned int b = 0; b < B; b++) tmp += mat[a][b] * in[b]; out[a] = tmp; } } void (mat_vec)(unsigned int A, unsigned int B, complex float out[A * B], const complex float in[A][B]) { for (unsigned int a = 0; a < A; a++) for (unsigned int b = 0; b < B; b++) out[a * B + b] = in[a][b]; } void (vec_mat)(unsigned int A, unsigned int B, complex float out[A][B], const complex float in[A * B]) { for (unsigned int a = 0; a < A; a++) for (unsigned int b = 0; b < B; b++) out[a][b] = in[a * B + b]; } complex float vec_dot(int N, const complex float x[N], const complex float y[N]) { cfl_acu_t scalar = 0.; // use double here to avoid errors // one could also look into the Kahan summation algorithm for (int k = 0; k < N; k++) scalar += x[k] * conjf(y[k]); return scalar; } // FIXME: this is not axpy void vec_axpy(long N, complex float x[N], complex float alpha, const complex float y[N]) { // #pragma omp parallel for for (long k = 0; k < N; k++) x[k] = alpha * y[k]; } void vec_saxpy(int N, complex float x[N], complex float alpha, const complex float y[N]) { for (int k = 0; k < N; k++) x[k] += alpha * y[k]; } void (gram_matrix)(int N, complex float cov[N][N], int L, const complex float data[N][L]) { #pragma omp parallel for for (int i = 0; i < N; i++) { for (int j = 0; j <= i; j++) { complex float val = vec_dot(L, data[i], data[j]); cov[j][i] = val; cov[i][j] = conj(val); } } } void (pack_tri_matrix)(int N, complex float cov[N * (N + 1) / 2], const complex float m[N][N]) { int l = 0; for (int i = 0; i < N; i++) for (int j = 0; j <= i; j++) cov[l++] = m[i][j]; } void (unpack_tri_matrix)(int N, complex float m[N][N], const complex float cov[N * (N + 1) / 2]) { int l = 0; for (int i = 0; i < N; i++) for (int j = 0; j <= i; j++) m[i][j] = cov[l++]; } void (gram_matrix2)(int N, complex float cov[N * (N + 1) / 2], int L, const complex float data[N][L]) { #if 0 int l = 0; for (int i = 0; i < N; i++) { for (int j = 0; j <= i; j++) { complex float val = vec_dot(L, data[i], data[j]); cov[l++] = conj(val); } } #else complex float c[N][N]; gram_matrix(N, c, L, data); pack_tri_matrix(N, cov, c); #endif } void gram_schmidt(int M, int N, float vals[M], complex float vecs[M][N]) { if (M > 1) gram_schmidt(M - 1, N, vals + 1, vecs + 1); for (int j = 1; j < M; j++) { complex float scalar = vec_dot(N, vecs[0], vecs[j]); vec_saxpy(N, vecs[0], -scalar, vecs[j]); } vals[0] = sqrtf(crealf(vec_dot(N, vecs[0], vecs[0]))); for (int k = 0; k < N; k++) vecs[0][k] /= vals[0]; } void (mat_transpose)(int A, int B, complex float dst[B][A], const complex float src[A][B]) { for (int i = 0; i < B; i++) for (int j = 0; j < A; j++) dst[i][j] = src[j][i]; // swap } void (mat_adjoint)(int A, int B, complex float dst[B][A], const complex float src[A][B]) { for (int i = 0; i < B; i++) for (int j = 0; j < A; j++) dst[i][j] = conjf(src[j][i]); // swap } void (mat_copy)(int A, int B, complex float dst[A][B], const complex float src[A][B]) { for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) dst[i][j] = src[i][j]; } void (mat_conj)(int A, int B, complex float dst[A][B], const complex float src[A][B]) { for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) dst[i][j] = conj(src[i][j]); } void (orthiter_noinit)(int M, int N, int iter, float val[M], complex float out[M][N], const complex float matrix[N][N]) { complex float tmp[M][N]; for (int n = 0; n < iter; n++) { mat_copy(M, N, tmp, out); mat_mul(M, N, N, out, tmp, matrix); gram_schmidt(M, N, val, out); } } void (orthiter)(int M, int N, int iter, float val[M], complex float out[M][N], const complex float matrix[N][N]) { mat_identity(M, N, out); orthiter_noinit(M, N, iter, val, out, matrix); } void cholesky_double(int N, complex double A[N][N]) { for (int i = 0; i < N; i++) { for (int j = 0; j < i; j++) { cfl_acu_t sum = A[i][j]; for (int k = 0; k < j; k++) sum -= A[i][k] * conj(A[j][k]); A[i][j] = sum / A[j][j]; } fl_acu_t sum = creal(A[i][i]); for (int k = 0; k < i; k++) sum -= creal(A[i][k] * conj(A[i][k])); assert(sum > 0.); A[i][i] = sqrt(sum); } for (int i = 0; i < N; i++) for (int j = 0; j < i; j++) A[j][i] = conj(A[i][j]); } // Tadeusz Banachiewicz void cholesky(int N, complex float A[N][N]) { #ifdef MAT_USE_LAPACK lapack_cholesky(N, A); for (int i = 0; i < N; i++) for (int j = 0; j < i; j++) A[j][i] = conjf(A[i][j]); #else #if 0 complex double B[N][N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) // B[i][j] = A[i][j]; cholesky_double(N, B); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) // A[i][j] = B[i][j]; #else for (int i = 0; i < N; i++) { for (int j = 0; j < i; j++) { cfl_acu_t sum = A[i][j]; for (int k = 0; k < j; k++) sum -= A[i][k] * conjf(A[j][k]); A[i][j] = sum / A[j][j]; } fl_acu_t sum = creal(A[i][i]); for (int k = 0; k < i; k++) sum -= crealf(A[i][k] * conjf(A[i][k])); assert(sum > 0.); A[i][i] = sqrt(sum); } for (int i = 0; i < N; i++) for (int j = 0; j < i; j++) A[j][i] = conjf(A[i][j]); #endif #endif } #if 0 static void backsubst_lower_double(int N, complex double x[N], complex double L[N][N], complex double b[N]) { for (int i = 0; i < N; i++) { complex double sum = b[i]; for (int j = 0; j < i; j++) sum -= x[j] * L[i][j]; x[i] = sum / L[i][i]; } } static void backsubst_upper_double(int N, complex double x[N], complex double L[N][N], complex double b[N]) { for (int i = N - 1; i >= 0; i--) { complex double sum = b[i]; for (int j = i + 1; j < N; j++) sum -= x[j] * L[i][j]; x[i] = sum / L[i][i]; } } void mat_adjoint_double(int A, int B, complex double dst[B][A], complex double src[A][B]) { for (int i = 0; i < B; i++) for (int j = 0; j < A; j++) dst[i][j] = conj(src[j][i]); // swap } void cholesky_solve_double(int N, complex double x[N], complex double L[N][N], complex double b[N]) { complex double y[N]; complex double T[N][N]; mat_adjoint_double(N, N, T, L); backsubst_lower_double(N, y, L, b); backsubst_upper_double(N, x, T, y); } #endif static void backsubst_lower(int N, complex float x[N], const complex float L[N][N], const complex float b[N]) { for (int i = 0; i < N; i++) { cfl_acu_t sum = b[i]; for (int j = 0; j < i; j++) sum -= x[j] * L[j][i]; x[i] = sum / L[i][i]; } } static void backsubst_upper(int N, complex float x[N], const complex float L[N][N], const complex float b[N]) { for (int i = N - 1; i >= 0; i--) { cfl_acu_t sum = b[i]; for (int j = i + 1; j < N; j++) sum -= x[j] * L[j][i]; x[i] = sum / L[i][i]; } } void (cholesky_solve)(int N, complex float x[N], const complex float L[N][N], const complex float b[N]) { complex float y[N]; backsubst_lower(N, y, L, b); backsubst_upper(N, x, L, y); } void thomas_algorithm(int N, complex float f[N], const complex float A[N][3], const complex float d[N]) { complex float c[N]; complex float e[N]; c[0] = A[0][2] / A[0][1]; e[0] = d[0] / A[0][1]; for (int i = 1; i < N; i++) { c[i] = A[i][2] / (A[i][1] - c[i - 1] * A[i][0]); e[i] = (d[i] - A[i][0] * e[i - 1]) / (A[i][1] - A[i][0] * c[i - 1]); } // backsubstitution f[N - 1] = e[N - 1]; for (int i = N - 2; 0 <= i; i--) f[i] = e[i] - c[i] * f[i + 1]; } bart-0.5.00/src/num/linalg.h000066400000000000000000000073351353046746100155520ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include #ifdef __cplusplus #error This file does not support C++ #endif extern void mat_identity(int A, int B, complex float x[A][B]); extern void mat_zero(int A, int B, complex float x[A][B]); extern void mat_gaussian(int A, int B, complex float x[A][B]); extern void mat_mul(int A, int B, int C, complex float x[A][C], const complex float y[A][B], const complex float z[B][C]); #define MVLA(x) __restrict__ (A) extern void mat_muladd(int A, int B, int C, complex float x[MVLA(A)][C], const complex float y[MVLA(A)][B], const complex float z[MVLA(B)][C]); extern void mat_add(int A, int B, complex float x[A][B], const complex float y[A][B], const complex float z[A][B]); extern void mat_transpose(int A, int B, complex float dst[B][A], const complex float src[A][B]); extern void mat_adjoint(int A, int B, complex float dst[B][A], const complex float src[A][B]); extern void mat_conj(int A, int B, complex float dst[B][A], const complex float src[A][B]); extern void mat_copy(int A, int B, complex float dst[A][B], const complex float src[A][B]); extern bool mat_inverse(unsigned int N, complex float dst[N][N], const complex float src[N][N]); extern void mat_pinv(unsigned int A, unsigned int B, complex float out[B][A], const complex float in[A][B]); extern void mat_vecmul(unsigned int A, unsigned int B, complex float out[A], const complex float mat[A][B], const complex float in[B]); extern void mat_kron(unsigned int A, unsigned int B, unsigned int C, unsigned int D, complex float out[A * C][B * D], const complex float in1[A][B], const complex float in2[C][D]); extern void mat_vec(unsigned int A, unsigned int B, complex float out[A * B], const complex float in[A][B]); extern void vec_mat(unsigned int A, unsigned int B, complex float out[A][B], const complex float in[A * B]); // extern complex double vec_dot(int N, const complex float x[N], const complex float y[N]); extern complex float vec_dot(int N, const complex float x[N], const complex float y[N]); extern void vec_saxpy(int N, complex float x[N], complex float alpha, const complex float y[N]); extern void gram_matrix(int N, complex float cov[N][N], int L, const complex float data[N][L]); extern void gram_schmidt(int M, int N, float val[N], complex float vecs[M][N]); extern void gram_matrix2(int N, complex float cov[N * (N + 1) / 2], int L, const complex float data[N][L]); extern void pack_tri_matrix(int N, complex float cov[N * (N + 1) / 2], const complex float m[N][N]); extern void unpack_tri_matrix(int N, complex float m[N][N], const complex float cov[N * (N + 1) / 2]); extern void orthiter_noinit(int M, int N, int iter, float vals[M], complex float out[M][N], const complex float matrix[N][N]); extern void orthiter(int M, int N, int iter, float vals[M], complex float out[M][N], const complex float matrix[N][N]); extern void cholesky(int N, complex float A[N][N]); extern void cholesky_solve(int N, complex float x[N], const complex float L[N][N], const complex float b[N]); extern void cholesky_double(int N, complex double A[N][N]); extern void cholesky_solve_double(int N, complex double x[N], const complex double L[N][N], const complex double b[N]); extern complex float vec_mean(long D, const complex float src[D]); extern void vec_axpy(long N, complex float x[N], complex float alpha, const complex float y[N]); extern void vec_sadd(long D, complex float alpha, complex float dst[D], const complex float src[D]); extern void thomas_algorithm(int N, complex float f[N], const complex float A[N][3], const complex float d[N]); bart-0.5.00/src/num/loop.c000066400000000000000000000053211353046746100152410ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker * * * various functions built around md_loop * No GPU support at the moment! */ #include #include "num/multind.h" #include "misc/nested.h" #include "loop.h" // typedef complex float (*sample_fun_t)(void* _data, const long pos[]); void md_zsample(unsigned int N, const long dims[N], complex float* out, void* data, sample_fun_t fun) { long strs[N]; md_calc_strides(N, strs, dims, 1); // we use size = 1 here long* strsp = strs; // because of clang NESTED(void, sample_kernel, (const long pos[])) { out[md_calc_offset(N, strsp, pos)] = fun(data, pos); }; md_loop(N, dims, sample_kernel); } void md_parallel_zsample(unsigned int N, const long dims[N], complex float* out, void* data, sample_fun_t fun) { long strs[N]; md_calc_strides(N, strs, dims, 1); // we use size = 1 here long* strsp = strs; // because of clang NESTED(void, sample_kernel, (const long pos[])) { out[md_calc_offset(N, strsp, pos)] = fun(data, pos); }; md_parallel_loop(N, dims, ~0u, sample_kernel); } struct map_data { unsigned int N; const long* strs; const complex float* in; void* data; map_fun_data_t fun; }; static complex float map_kernel(void* _data, const long pos[]) { struct map_data* data = _data; return data->fun(data->data, data->in[md_calc_offset(data->N, data->strs, pos)]); } static void md_zmap_const(unsigned int N, const long dims[N], complex float* out, const complex float* in, void* data, map_fun_data_t fun) { struct map_data sdata; sdata.N = N; long strs[N]; md_calc_strides(N, strs, dims, 1); // we use size = 1 here sdata.strs = strs; sdata.in = in; sdata.data = data; sdata.fun = fun; md_zsample(N, dims, out, &sdata, map_kernel); } static complex float map_data_kernel(void* _data, complex float arg) { map_fun_t fun = _data; return fun(arg); } void md_zmap(unsigned int N, const long dims[N], complex float* out, const complex float* in, map_fun_t fun) { md_zmap_const(N, dims, out, in, (void*)fun, map_data_kernel); } struct gradient_data { unsigned int N; const complex float* grad; }; static complex float gradient_kernel(void* _data, const long pos[]) { struct gradient_data* data = _data; complex float val = 0.; for (unsigned int i = 0; i < data->N; i++) val += pos[i] * data->grad[i]; return val; } void md_zgradient(unsigned int N, const long dims[N], complex float* out, const complex float grad[N]) { struct gradient_data data = { N, grad }; md_zsample(N, dims, out, &data, gradient_kernel); } bart-0.5.00/src/num/loop.h000066400000000000000000000021321353046746100152430ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include "misc/cppwrap.h" typedef complex float (*sample_fun_t)(void* _data, const long pos[]); extern void md_zsample(unsigned int N, const long dims[__VLA(N)], complex float* z, void* data, sample_fun_t fun); extern void md_parallel_zsample(unsigned int N, const long dims[__VLA(N)], complex float* z, void* data, sample_fun_t fun); extern void md_zgradient(unsigned int N, const long dims[__VLA(N)], complex float* out, const complex float grad[__VLA(N)]); typedef complex float (*map_fun_data_t)(void* _data, complex float arg); typedef complex float (*map_fun_t)(complex float arg); extern void md_zmap_data(unsigned int N, const long dims[__VLA(N)], complex float* out, const complex float* in, void* data, map_fun_data_t fun); extern void md_zmap(unsigned int N, const long dims[__VLA(N)], complex float* out, const complex float* in, map_fun_t fun); #include "misc/cppwrap.h" bart-0.5.00/src/num/mdfft.c000066400000000000000000000162031353046746100153710ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Author: * 2015 Martin Uecker */ #define _GNU_SOURCE #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "misc/misc.h" #include "mdfft.h" static void rot45z2(unsigned int D, unsigned int M, const long dim[D], const long ostr[D], complex float* optr, const long istr[D], const complex float* iptr) { assert(M < D); assert(2 == dim[M]); assert(optr != iptr); long dims2[D]; md_copy_dims(D, dims2, dim); dims2[M] = 1; long ostr2[D]; md_copy_strides(D, ostr2, ostr); ostr2[M] *= 2; long istr2[D]; md_copy_strides(D, istr2, istr); istr2[M] *= 2; md_zadd2(D, dims2, ostr2, optr , istr2, iptr, istr2, ((void*)iptr) + istr[M]); md_zsub2(D, dims2, ostr2, ((void*)optr) + ostr[M], istr2, iptr, istr2, ((void*)iptr) + istr[M]); } static unsigned int find_bit(unsigned long N) { return ffsl(N) - 1; } static unsigned int next_powerof2(unsigned int x) { x--; assert(x <= (UINT32_MAX >> 1)); for (unsigned int i = 0, n = 1; i < 5; i++, n *= 2) x = (x >> n) | x; return x + 1; } static void compute_chirp(unsigned int L, bool dir, unsigned int M, complex float krn[M]) { krn[0] = 1.; for (unsigned int i = 1; i < M; i++) krn[i] = 0.; for (unsigned int i = 1; i < M; i++) { if (i < L) { complex float v = cexpf((dir ? -1. : 1.) * M_PI * 1.i * (float)(i * i) / (float)L); krn[i] = v; krn[M - i] = v; } } } static void bluestein(unsigned int N, const long dims[N], unsigned long flags, unsigned long dirs, const long ostrs[N], complex float* dst, const long istrs[N], const complex float* in) { unsigned int D = find_bit(flags); unsigned int M = next_powerof2(2 * dims[D] - 1); assert(M >= 2 * dims[D] - 1); assert(0 == MD_CLEAR(flags, D)); /* Bluestein * * Transform DFT into convolution according to * * \ksi_N^{nk} = \ksi_N^{-(k-n)^2/2 + n^2/2 + k^2/2} * * ... and use fft of different size to implement it. */ long kdims[N]; md_singleton_dims(N, kdims); kdims[D] = M; long kstrs[N]; md_calc_strides(N, kstrs, kdims, CFL_SIZE); complex float* xkrn = md_alloc(N, kdims, CFL_SIZE); compute_chirp(dims[D], MD_IS_SET(dirs, D), M, xkrn); complex float* krn = md_alloc_sameplace(N, kdims, CFL_SIZE, dst); md_copy(N, kdims, krn, xkrn, CFL_SIZE); md_free(xkrn); complex float* fkrn = md_alloc_sameplace(N, kdims, CFL_SIZE, dst); md_fft(N, kdims, MD_BIT(D), MD_FFT_FORWARD, fkrn, krn); long bdims[N]; md_copy_dims(N, bdims, dims); bdims[D] = M; long bstrs[N]; md_calc_strides(N, bstrs, bdims, CFL_SIZE); complex float* btmp = md_alloc_sameplace(N, bdims, CFL_SIZE, dst); md_clear(N, bdims, btmp, CFL_SIZE); md_zmulc2(N, dims, bstrs, btmp, istrs, in, kstrs, krn); md_fft2(N, bdims, MD_BIT(D), MD_FFT_INVERSE, bstrs, btmp, bstrs, btmp); md_zmul2(N, bdims, bstrs, btmp, bstrs, btmp, kstrs, fkrn); md_fft2(N, bdims, MD_BIT(D), MD_FFT_FORWARD, bstrs, btmp, bstrs, btmp); md_zsmul(1, MD_DIMS(M), krn, krn, 1. / (float)M); md_zmulc2(N, dims, ostrs, dst, bstrs, btmp, kstrs, krn); md_free(fkrn); md_free(krn); md_free(btmp); } static void compute_twiddle(unsigned int n, unsigned int m, complex float t[n][m]) { for (unsigned int i = 0; i < n; i++) for (unsigned int j = 0; j < m; j++) t[i][j] = cexpf(-2.i * M_PI * (float)(i * j) / (float)(n * m)); } static void cooley_tukey(unsigned int N, const long dims[N], unsigned int D, unsigned int a, unsigned int b, unsigned long flags, unsigned long dirs, const long ostr[N], complex float* dst, const long istr[N], const complex float* in) { /* Cooley-Tukey * * With N = A * B, \ksi_N^N = 1, split into smaller FFTs: * * \ksi_N^{(B * i + j)(l + A * k)} * = \ksi_N^{B * i * l + A * j * k + j * l} * = \ksi_N^{B * i * l} \ksi_N^{A * j * k} \ksi_N^{j * l} * = \ksi_A^{i * l} \ksi_N^{j * l} \ksi_B^{j * k} */ long xdims[N + 1]; md_copy_dims(N, xdims, dims); xdims[D] = a; xdims[N] = b; long astr[N + 1]; md_copy_strides(N, astr, istr); astr[D] = istr[D] * 1; astr[N] = istr[D] * a; long bstr[N + 1]; md_copy_strides(N, bstr, ostr); bstr[D] = ostr[D] * b; bstr[N] = ostr[D] * 1; unsigned long flags1 = 0; unsigned long flags2 = MD_CLEAR(flags, D); long tdims[N + 1]; long tstrs[N + 1]; md_select_dims(N + 1, MD_BIT(D) | MD_BIT(N), tdims, xdims); md_calc_strides(N + 1, tstrs, tdims, CFL_SIZE); complex float (*xtw)[b][a] = xmalloc(a * b * CFL_SIZE); compute_twiddle(b, a, *xtw); complex float* tw = md_alloc_sameplace(N + 1, tdims, CFL_SIZE, dst); md_copy(N + 1, tdims, tw, &(*xtw)[0][0], CFL_SIZE); xfree(xtw); md_fft2(N + 1, xdims, MD_SET(flags1, N), dirs, bstr, dst, astr, in); (MD_IS_SET(dirs, D) ? md_zmulc2 : md_zmul2)(N + 1, xdims, bstr, dst, bstr, dst, tstrs, tw); md_fft2(N + 1, xdims, MD_SET(flags2, D), dirs, bstr, dst, bstr, dst); md_free(tw); } static bool check_strides(unsigned int N, const long ostr[N], const long istr[N]) { bool ret = true; for (unsigned int i = 0; i < N; i++) ret = ret & (ostr[i] == istr[i]); return ret; } static unsigned int find_factor(unsigned int N) { for (unsigned int i = 2; i < N; i++) if (0 == N % i) return i; return N; } void md_fft2(unsigned int N, const long dims[N], unsigned long flags, unsigned long dirs, const long ostr[N], complex float* dst, const long istr[N], const complex float* in) { if (0 == flags) { if (dst == in) { if (!check_strides(N, ostr, istr)) { // detect and use inplace transpose? long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); complex float* tmp = md_alloc_sameplace(N, dims, CFL_SIZE, dst); md_copy2(N, dims, strs, tmp, istr, in, CFL_SIZE); md_copy2(N, dims, ostr, dst, strs, tmp, CFL_SIZE); md_free(tmp); } return; } md_copy2(N, dims, ostr, dst, istr, in, CFL_SIZE); return; } unsigned int D = find_bit(flags); if (1 == dims[D]) { md_fft2(N, dims, MD_CLEAR(flags, D), dirs, ostr, dst, istr, in); return; } if (2 == dims[D]) { if (dst == in) { long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); complex float* tmp = md_alloc_sameplace(N, dims, CFL_SIZE, dst); md_fft2(N, dims, MD_CLEAR(flags, D), dirs, strs, tmp, istr, in); rot45z2(N, D, dims, ostr, dst, strs, tmp); md_free(tmp); } else { // the nufft may do the transpose rot45z2(N, D, dims, ostr, dst, istr, in); md_fft2(N, dims, MD_CLEAR(flags, D), dirs, ostr, dst, ostr, dst); } return; } unsigned int a = find_factor(dims[D]); unsigned int b = dims[D] / a; if (1 == b) { // prime bluestein(N, dims, MD_BIT(D), dirs, ostr, dst, istr, in); md_fft2(N, dims, MD_CLEAR(flags, D), dirs, ostr, dst, ostr, dst); } else { cooley_tukey(N, dims, D, a, b, flags, dirs, ostr, dst, istr, in); } } void md_fft(unsigned int N, const long dims[N], unsigned long flags, unsigned long dirs, complex float* dst, const complex float* in) { long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); md_fft2(N, dims, flags, dirs, strs, dst, strs, in); } bart-0.5.00/src/num/mdfft.h000066400000000000000000000007061353046746100153770ustar00rootroot00000000000000 #ifndef _MD_FFT_H #define _MD_FFT_H 1 #define MD_FFT_FORWARD 0u #define MD_FFT_INVERSE (~0u) extern void md_fft2(unsigned int N, const long dims[N], unsigned long flags, unsigned long dirs, const long ostr[N], complex float* dst, const long istr[N], const complex float* in); extern void md_fft(unsigned int N, const long dims[N], unsigned long flags, unsigned long dirs, complex float* dst, const complex float* in); #endif // _MD_FFT_H bart-0.5.00/src/num/mem.c000066400000000000000000000076021353046746100150520ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * */ #include #include #ifdef _OPENMP #include #endif #include "misc/misc.h" #include "misc/debug.h" #include "mem.h" bool memcache = true; void memcache_off(void) { memcache = false; } struct mem_s { const void* ptr; size_t len; bool device; bool free; int device_id; int thread_id; struct mem_s* next; }; static struct mem_s* mem_list = NULL; static bool inside_p(const struct mem_s* rptr, const void* ptr) { return (ptr >= rptr->ptr) && (ptr < rptr->ptr + rptr->len); } static struct mem_s* search(const void* ptr, bool remove) { struct mem_s* rptr = NULL; #pragma omp critical { struct mem_s** nptr = &mem_list; while (true) { rptr = *nptr; if (NULL == rptr) break; if (inside_p(rptr, ptr)) { if (remove) *nptr = rptr->next; break; } nptr = &(rptr->next); } } return rptr; } static bool free_check_p(const struct mem_s* rptr, size_t size, int dev, int tid) { return (rptr->free && (rptr->device_id == dev) && (rptr->len >= size) && ((-1 == tid) || (rptr->thread_id == tid))); } static struct mem_s** find_free_unsafe(size_t size, int dev, int tid) { struct mem_s* rptr = NULL; struct mem_s** nptr = &mem_list; while (true) { rptr = *nptr; if (NULL == rptr) break; if (free_check_p(rptr, size, dev, tid)) break; nptr = &(rptr->next); } return nptr; } static struct mem_s* find_free(size_t size, int dev) { struct mem_s* rptr = NULL; #pragma omp critical { rptr = *find_free_unsafe(size, dev, -1); if (NULL != rptr) rptr->free = false; } return rptr; } static void insert(const void* ptr, size_t len, bool device, int dev) { PTR_ALLOC(struct mem_s, nptr); nptr->ptr = ptr; nptr->len = len; nptr->device = device; nptr->device_id = dev; #ifdef _OPENMP nptr->thread_id = omp_get_thread_num(); #else nptr->thread_id = -1; #endif nptr->free = false; #pragma omp critical { nptr->next = mem_list; mem_list = PTR_PASS(nptr); } } void memcache_clear(int dev, void (*device_free)(const void*x)) { struct mem_s* nptr = NULL; if (!memcache) return; do { #pragma omp critical { #ifdef _OPENMP int tid = omp_get_thread_num(); #else int tid = -1; #endif struct mem_s** rptr = find_free_unsafe(0, dev, tid); nptr = *rptr; // remove from list if (NULL != nptr) *rptr = nptr->next; } if (NULL != nptr) { assert(nptr->device); debug_printf(DP_DEBUG3, "Freeing %ld bytes. (DID: %d TID: %d)\n\n", nptr->len, nptr->device_id, nptr->thread_id); device_free(nptr->ptr); xfree(nptr); } } while (NULL != nptr); } bool mem_ondevice(const void* ptr) { if (NULL == ptr) return false; struct mem_s* p = search(ptr, false); bool r = ((NULL != p) && p->device); return r; } bool mem_device_accessible(const void* ptr) { struct mem_s* p = search(ptr, false); return (NULL != p); } void mem_device_free(void* ptr, void (*device_free)(const void* ptr)) { struct mem_s* nptr = search(ptr, !memcache); assert(NULL != nptr); assert(nptr->ptr == ptr); assert(nptr->device); if (memcache) { assert(!nptr->free); nptr->free = true; } else { device_free(ptr); xfree(nptr); } } void* mem_device_malloc(int device, long size, void* (*device_alloc)(size_t)) { if (memcache) { struct mem_s* nptr = find_free(size, device); if (NULL != nptr) { assert(nptr->device); assert(!nptr->free); #ifdef _OPENMP nptr->thread_id = omp_get_thread_num(); #else nptr->thread_id = -1; #endif return (void*)(nptr->ptr); } } void* ptr = device_alloc(size); insert(ptr, size, true, device); return ptr; } bart-0.5.00/src/num/mem.h000066400000000000000000000005651353046746100150600ustar00rootroot00000000000000 extern void memcache_off(void); extern void memcache_clear(int device, void (*device_free)(const void* x)); extern _Bool mem_ondevice(const void* ptr); extern _Bool mem_device_accessible(const void* ptr); extern void mem_device_free(void* ptr, void (*device_free)(const void* x)); extern void* mem_device_malloc(int device, long size, void* (*device_alloc)(size_t)); bart-0.5.00/src/num/multind.c000066400000000000000000001124321353046746100157460ustar00rootroot00000000000000/* Copyright 2013-2015 The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * Copyright 2017. Intel Corporation. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2013 Frank Ong * 2017 Michael J. Anderson * * Generic operations on multi-dimensional arrays. Most functions * come in two flavours: * * 1. A basic version which takes the number of dimensions, an array * of long integers specifing the size of each dimension, the pointers * to the data, and the size of each element and other required parameters. * The data is assumed to be stored in column-major format. * * 2. An extended version which takes an array of long integers which * specifies the strides for each argument. * * All functions should work on CPU and GPU and md_copy can be used * to copy between CPU and GPU. * */ #define _GNU_SOURCE #include #include #include #include #include #include "misc/misc.h" #include "misc/types.h" #include "misc/debug.h" #include "misc/nested.h" #include "num/optimize.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "multind.h" /** * Generic functions which loops over all dimensions of a set of * multi-dimensional arrays and calls a given function for each position. */ void md_nary(unsigned int C, unsigned int D, const long dim[D], const long* str[C], void* ptr[C], md_nary_fun_t fun) { if (0 == D) { NESTED_CALL(fun, (ptr)); return; } for (long i = 0; i < dim[D - 1]; i++) { void* moving_ptr[C]; for (unsigned int j = 0; j < C; j++) moving_ptr[j] = ptr[j] + i * str[j][D - 1]; md_nary(C, D - 1, dim, str, moving_ptr, fun); } } /** * Generic functions which loops over all dimensions of a set of * multi-dimensional arrays and calls a given function for each position. * This functions tries to parallelize over the dimensions indicated * with flags. */ void md_parallel_nary(unsigned int C, unsigned int D, const long dim[D], unsigned long flags, const long* str[C], void* ptr[C], md_nary_fun_t fun) { if (0 == flags) { md_nary(C, D, dim, str, ptr, fun); return; } long dimc[D]; md_select_dims(D, ~flags, dimc, dim); // Collect all parallel dimensions int nparallel = 0; int parallel_b[D]; long parallel_dim[D]; long total_iterations = 1L; while (0 != flags) { int b = ffsl(flags & -flags) - 1; assert(MD_IS_SET(flags, b)); flags = MD_CLEAR(flags, b); debug_printf(DP_DEBUG4, "Parallelize: %d\n", dim[b]); parallel_b[nparallel] = b; parallel_dim[nparallel] = dim[b]; total_iterations *= parallel_dim[nparallel]; nparallel++; } #pragma omp parallel for for (long i = 0; i < total_iterations; i++) { // Recover place in parallel iteration space long iter_i[D]; long ii = i; for (int p = nparallel - 1; p >= 0; p--) { iter_i[p] = ii % parallel_dim[p]; ii /= parallel_dim[p]; } void* moving_ptr[C]; for (unsigned int j = 0; j < C; j++) { moving_ptr[j] = ptr[j]; for(int p = 0; p < nparallel; p++) moving_ptr[j] += iter_i[p] * str[j][parallel_b[p]]; } md_nary(C, D, dimc, str, moving_ptr, fun); } } static void md_parallel_loop_r(unsigned int D, unsigned int N, const long dim[static N], unsigned int flags, const long pos[static N], md_loop_fun_t fun) { if (0 == D) { NESTED_CALL(fun, (pos)); return; } D--; // we need to make a copy because firstprivate needs to see // an array instead of a pointer long pos_copy[N]; for (unsigned int i = 0; i < N; i++) pos_copy[i] = pos[i]; #pragma omp parallel for firstprivate(pos_copy) if ((1 < dim[D]) && (flags & (1 << D))) for (int i = 0; i < dim[D]; i++) { pos_copy[D] = i; md_parallel_loop_r(D, N, dim, flags, pos_copy, fun); } } /** * Generic function which loops over all dimensions and calls a given * function passing the current indices as argument. * * Runs fun(data, position) for all position in dim * */ void md_parallel_loop(unsigned int D, const long dim[static D], unsigned long flags, md_loop_fun_t fun) { long pos[D]; md_parallel_loop_r(D, D, dim, flags, pos, fun); } static void md_loop_r(unsigned int D, const long dim[D], long pos[D], md_loop_fun_t fun) { if (0 == D) { NESTED_CALL(fun, (pos)); return; } D--; for (pos[D] = 0; pos[D] < dim[D]; pos[D]++) md_loop_r(D, dim, pos, fun); } /** * Generic function which loops over all dimensions and calls a given * function passing the current indices as argument. * * Runs fun( position ) for all position in dim * */ void md_loop(unsigned int D, const long dim[D], md_loop_fun_t fun) { long pos[D]; md_loop_r(D, dim, pos, fun); } /** * Computes the next position. Returns true until last index. */ bool md_next(unsigned int D, const long dims[D], unsigned long flags, long pos[D]) { if (0 == D--) return false; if (md_next(D, dims, flags, pos)) return true; if (MD_IS_SET(flags, D)) { assert((0 <= pos[D]) && (pos[D] < dims[D])); if (++pos[D] < dims[D]) return true; pos[D] = 0; } return false; } /** * Returns offset for position in a multidimensional array * * return pos[0]*strides[0] + ... + pos[D-1]*strides[D-1] * * @param D number of dimensions * @param dim dimensions array */ long md_calc_offset(unsigned int D, const long strides[D], const long position[D]) { long pos = 0; for (unsigned int i = 0; i < D; i++) pos += strides[i] * position[i]; return pos; } static long md_calc_size_r(unsigned int D, const long dim[D], size_t size) { if (0 == D) return size; return md_calc_size_r(D - 1, dim, size * dim[D - 1]); } /** * Returns the number of elements * * return dim[0]*dim[1]*...*dim[D-1] * * @param D number of dimensions * @param dim dimensions array */ long md_calc_size(unsigned int D, const long dim[D]) { return md_calc_size_r(D, dim, 1); } /** * Computes the number of smallest dimensions which are stored * contineously, i.e. can be accessed as a block of memory. * */ unsigned int md_calc_blockdim(unsigned int D, const long dim[D], const long str[D], size_t size) { long dist = size; unsigned int i = 0; for (i = 0; i < D; i++) { if (!((str[i] == dist) || (dim[i] == 1))) break; dist *= dim[i]; } return i; } /** * Copy dimensions specified by flags and set remaining dimensions to 1 * * odims = [ 1 idims[1] idims[2] 1 1 idims[5] ] * * @param D number of dimensions * @param flags bitmask specifying which dimensions to copy * @param odims output dimensions * @param idims input dimensions */ void md_select_dims(unsigned int D, unsigned long flags, long odims[D], const long idims[D]) { md_copy_dims(D, odims, idims); for (unsigned int i = 0; i < D; i++) if (!MD_IS_SET(flags, i)) odims[i] = 1; } /** * Copy dimensions * * odims[i] = idims[i] */ void md_copy_dims(unsigned int D, long odims[D], const long idims[D]) { memcpy(odims, idims, D * sizeof(long)); } /** * Copy strides * * ostrs[i] = istrs[i] */ void md_copy_strides(unsigned int D, long ostrs[D], const long istrs[D]) { memcpy(ostrs, istrs, D * sizeof(long)); } /** * Set all dimensions to value * * dims[i] = val */ void md_set_dims(unsigned int D, long dims[D], long val) { for (unsigned int i = 0; i < D; i++) dims[i] = val; } /** * returns whether or not @param pos is a valid index of an array of dimension @param dims */ bool md_is_index(unsigned int D, const long pos[D], const long dims[D]) { if (D == 0) return true; return ((pos[0] >= 0) && (pos[0] < dims[0]) && md_is_index(D - 1, pos + 1, dims + 1)); } /** * return whether some other dimensions are >1 */ bool md_check_dimensions(unsigned int N, const long dims[N], unsigned int flags) { long d[N]; md_select_dims(N, ~flags, d, dims); return (1 != md_calc_size(N, d)); } /* * compute non-trivial (> 1) dims */ unsigned long md_nontriv_dims(unsigned int D, const long dims[D]) { unsigned long flags = 0; for (unsigned int i = 0; i < D; i++) if (dims[i] > 1) flags = MD_SET(flags, i); return flags; } /* * compute non-trivial (!= 0) strides */ unsigned long md_nontriv_strides(unsigned int D, const long strs[D]) { unsigned long flags = 0; for (unsigned int i = 0; i < D; i++) if (strs[i] != 0) flags = MD_SET(flags, i); return flags; } /** * Set all dimensions to one * * dims[i] = 1 */ void md_singleton_dims(unsigned int D, long dims[D]) { for (unsigned int i = 0; i < D; i++) dims[i] = 1; } /** * Set all strides to one * * dims[i] = 1 */ void md_singleton_strides(unsigned int D, long strs[D]) { for (unsigned int i = 0; i < D; i++) strs[i] = 0; } /** * Check dimensions for compatibility. Dimensions must be equal or * where indicated by a set bit in flags one must be equal to one * in atleast one of the arguments. */ bool md_check_compat(unsigned int D, unsigned long flags, const long dim1[D], const long dim2[D]) { if (0 == D) return true; D--; if ((dim1[D] == dim2[D]) || (MD_IS_SET(flags, D) && ((1 == dim1[D]) || (1 == dim2[D])))) return md_check_compat(D, flags, dim1, dim2); return false; } void md_merge_dims(unsigned int N, long out_dims[N], const long dims1[N], const long dims2[N]) { assert(md_check_compat(N, ~0, dims1, dims2)); for (unsigned int i = 0; i < N; i++) out_dims[i] = (1 == dims1[i]) ? dims2[i] : dims1[i]; } /** * dim1 must be bounded by dim2 where a bit is set */ bool md_check_bounds(unsigned int D, unsigned long flags, const long dim1[D], const long dim2[D]) { if (0 == D--) return true; if (!MD_IS_SET(flags, D) || (dim1[D] <= dim2[D])) return md_check_bounds(D, flags, dim1, dim2); return false; } /** * Set the output's flagged dimensions to the minimum of the two input dimensions * * odims = [ MIN(idims1[0],idims2[0] ... MIN(idims1[D-1],idims2[D-1]) ] * * @param D number of dimensions * @param flags bitmask specifying which dimensions to minimize * @param odims output dimensions * @param idims1 input 1 dimensions * @param idims2 input 2 dimensions */ void md_min_dims(unsigned int D, unsigned long flags, long odims[D], const long idims1[D], const long idims2[D]) { for (unsigned int i = 0; i < D; i++) if (MD_IS_SET(flags, i)) odims[i] = MIN(idims1[i], idims2[i]); } /** * Set the output's flagged dimensions to the maximum of the two input dimensions * * odims = [ MAX(idims1[0],idims2[0] ... MAX(idims1[D-1],idims2[D-1]) ] * * @param D number of dimensions * @param flags bitmask specifying which dimensions to maximize * @param odims output dimensions * @param idims1 input 1 dimensions * @param idims2 input 2 dimensions */ void md_max_dims(unsigned int D, unsigned long flags, long odims[D], const long idims1[D], const long idims2[D]) { for (unsigned int i = 0; i < D; i++) if (MD_IS_SET(flags, i)) odims[i] = MAX(idims1[i], idims2[i]); } /** * Zero out array (with strides) * * ptr[i] = 0 */ void md_clear2(unsigned int D, const long dim[D], const long str[D], void* ptr, size_t size) { const long (*nstr[1])[D] = { (const long (*)[D])str }; #ifdef USE_CUDA bool use_gpu = cuda_ondevice(ptr); #endif unsigned long flags = 0; for (unsigned int i = 0; i < D; i++) if (0 == str[i]) flags |= MD_BIT(i); long dim2[D]; md_select_dims(D, ~flags, dim2, dim); NESTED(void, nary_clear, (struct nary_opt_data_s* opt_data, void* ptr[])) { size_t size2 = size * opt_data->size; #ifdef USE_CUDA if (use_gpu) { cuda_clear(size2, ptr[0]); return; } #endif memset(ptr[0], 0, size2); }; optimized_nop(1, MD_BIT(0), D, dim2, nstr, (void*[1]){ ptr }, (size_t[1]){ size }, nary_clear); } /** * Calculate strides in column-major format * (smallest index is sequential) * * @param D number of dimensions * @param array of calculates strides * @param dim array of dimensions * @param size of a single element */ long* md_calc_strides(unsigned int D, long str[D], const long dim[D], size_t size) { long old = size; for (unsigned int i = 0; i < D; i++) { str[i] = (1 == dim[i]) ? 0 : old; old *= dim[i]; } return str; } /** * Zero out array (without strides) * * ptr[i] = 0 * * @param D number of dimensions * @param dim dimensions array * @param ptr pointer to data to clear * @param size sizeof() */ void md_clear(unsigned int D, const long dim[D], void* ptr, size_t size) { md_clear2(D, dim, MD_STRIDES(D, dim, size), ptr, size); } /** * Copy array (with strides) * * optr[i] = iptr[i] */ void md_copy2(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr[D], const void* iptr, size_t size) { #if 0 // this is for a fun comparison between our copy engine and FFTW extern void fft2(unsigned int D, const long dim[D], unsigned int flags, const long ostr[D], void* optr, const long istr[D], const void* iptr); if (sizeof(complex float) == size) fft2(D, dim, 0, ostr, optr, istr, iptr); #endif #ifdef USE_CUDA bool use_gpu = cuda_ondevice(optr) || cuda_ondevice(iptr); #if 1 long tostr[D]; long tistr[D]; long tdims[D]; md_copy_strides(D, tostr, ostr); md_copy_strides(D, tistr, istr); md_copy_dims(D, tdims, dim); long (*nstr2[2])[D] = { &tostr, &tistr }; int ND = optimize_dims(2, D, tdims, nstr2); size_t sizes[2] = { size, size }; int skip = min_blockdim(2, ND, tdims, nstr2, sizes); long ostr2 = (*nstr2[0])[skip]; long istr2 = (*nstr2[1])[skip]; if (use_gpu && (ND - skip > 0) && (ostr2 > 0) && (istr2 > 0)) { void* nptr[2] = { optr, (void*)iptr }; long sizes[2] = { md_calc_size(skip, tdims) * size, tdims[skip] }; skip++; const long* nstr[2] = { *nstr2[0] + skip, *nstr2[1] + skip }; long* sizesp = sizes; // because of clang NESTED(void, nary_strided_copy, (void* ptr[])) { debug_printf(DP_DEBUG4, "CUDA 2D copy %ld %ld %ld %ld %ld %ld\n", sizes[0], sizes[1], ostr2, istr2, nptr[0], nptr[1]); cuda_memcpy_strided(sizesp, ostr2, ptr[0], istr2, ptr[1]); }; md_nary(2, ND - skip, tdims + skip, nstr, nptr, nary_strided_copy); return; } #endif #endif const long (*nstr[2])[D] = { (const long (*)[D])ostr, (const long (*)[D])istr }; NESTED(void, nary_copy, (struct nary_opt_data_s* opt_data, void* ptr[])) { size_t size2 = size * opt_data->size; #ifdef USE_CUDA if (use_gpu) { cuda_memcpy(size2, ptr[0], ptr[1]); return; } #endif memcpy(ptr[0], ptr[1], size2); }; optimized_nop(2, MD_BIT(0), D, dim, nstr, (void*[2]){ optr, (void*)iptr }, (size_t[2]){ size, size }, nary_copy); } /** * Copy array (without strides) * * optr[i] = iptr[i] */ void md_copy(unsigned int D, const long dim[D], void* optr, const void* iptr, size_t size) { long str[D]; md_calc_strides(D, str, dim, size); md_copy2(D, dim, str, optr, str, iptr, size); } #ifdef USE_CUDA // copied from flpmath.c static void* gpu_constant(const void* vp, size_t size) { return md_gpu_move(1, (long[1]){ 1 }, vp, size); } #endif /** * Fill array with value pointed by pointer (with strides) * * ptr[i] = iptr[0] */ void md_fill2(unsigned int D, const long dim[D], const long str[D], void* ptr, const void* iptr, size_t size) { #ifdef USE_CUDA if (cuda_ondevice(ptr) && (!cuda_ondevice(iptr))) { void* giptr = gpu_constant(iptr, size); md_fill2(D, dim, str, ptr, giptr, size); md_free(giptr); return; } #endif long istr[D]; md_singleton_strides(D, istr); md_copy2(D, dim, str, ptr, istr, iptr, size); } /** * Fill array with value pointed by pointer (without strides) * * ptr[i] = iptr[0] */ void md_fill(unsigned int D, const long dim[D], void* ptr, const void* iptr, size_t size) { md_fill2(D, dim, MD_STRIDES(D, dim, size), ptr, iptr, size); } /** * Swap values between a number of arrays (with strides) */ void md_circular_swap2(unsigned int M, unsigned int D, const long dims[D], const long* strs[M], void* ptr[M], size_t size) { size_t sizes[M]; for (unsigned int i = 0; i < M; i++) sizes[i] = size; const long (*nstrs[M])[D]; for (unsigned int i = 0; i < M; i++) nstrs[i] = (const long (*)[D])strs[i]; NESTED(void, nary_swap, (struct nary_opt_data_s* opt_data, void* ptr[])) { size_t size2 = size * opt_data->size; char* tmp = (size2 < 32) ? alloca(size2) : xmalloc(size2); #ifdef USE_CUDA assert(!cuda_ondevice(ptr[0])); assert(!cuda_ondevice(ptr[1])); #endif memcpy(tmp, ptr[0], size2); for (unsigned int i = 0; i < M - 1; i++) memcpy(ptr[i], ptr[i + 1], size2); memcpy(ptr[M - 1], tmp, size2); if (size2 >= 32) xfree(tmp); }; optimized_nop(M, (1 << M) - 1, D, dims, nstrs, ptr, sizes, nary_swap); } /** * Swap values between a number of arrays */ void md_circular_swap(unsigned M, unsigned int D, const long dims[D], void* ptr[M], size_t size) { long strs[M][D]; md_calc_strides(D, strs[0], dims, size); const long* strp[M]; strp[0] = strs[0]; for (unsigned int i = 1; i < M; i++) { md_copy_strides(D, strs[i], strs[0]); strp[i] = strs[i]; } md_circular_swap2(M, D, dims, strp, ptr, size); } /** * Swap values between two arrays (with strides) * * iptr[i] = optr[i] and optr[i] = iptr[i] */ void md_swap2(unsigned int D, const long dim[D], const long ostr[D], void* optr, const long istr[D], void* iptr, size_t size) { md_circular_swap2(2, D, dim, (const long*[2]){ ostr, istr }, (void*[2]){ optr, iptr }, size); } /** * Swap values between two arrays (without strides) * * iptr[i] = optr[i] and optr[i] = iptr[i] */ void md_swap(unsigned int D, const long dim[D], void* optr, void* iptr, size_t size) { long str[D]; md_calc_strides(D, str, dim, size); md_swap2(D, dim, str, optr, str, iptr, size); } /** * Move a block from an array to another array (with strides) * */ void md_move_block2(unsigned int D, const long dim[D], const long opos[D], const long odim[D], const long ostr[D], void* optr, const long ipos[D], const long idim[D], const long istr[D], const void* iptr, size_t size) { for (unsigned int i = 0; i < D; i++) { assert(dim[i] <= odim[i]); assert(dim[i] <= idim[i]); assert((0 <= opos[i]) && (opos[i] <= odim[i] - dim[i])); assert((0 <= ipos[i]) && (ipos[i] <= idim[i] - dim[i])); } long ioff = md_calc_offset(D, istr, ipos); long ooff = md_calc_offset(D, ostr, opos); md_copy2(D, dim, ostr, optr + ooff, istr, iptr + ioff, size); } /** * Move a block from an array to another array (without strides) * */ void md_move_block(unsigned int D, const long dim[D], const long opos[D], const long odim[D], void* optr, const long ipos[D], const long idim[D], const void* iptr, size_t size) { md_move_block2(D, dim, opos, odim, MD_STRIDES(D, odim, size), optr, ipos, idim, MD_STRIDES(D, idim, size), iptr, size); } /** * Copy a block from an array to another array (with strides) * * Block dimensions are min(idim , odim) * * if idim[d] > odim[d], then optr[i] = iptr[pos + i] for 0 <= i < odim[d] * * if idim[d] < odim[d], then optr[pos + i] = iptr[i] for 0 <= i < idim[d] * */ void md_copy_block2(unsigned int D, const long pos[D], const long odim[D], const long ostr[D], void* optr, const long idim[D], const long istr[D], const void* iptr, size_t size) { long dim[D]; long ipos[D]; long opos[D]; for (unsigned int i = 0; i < D; i++) { assert((idim[i] != odim[i]) || (0 == pos[i])); dim[i] = MIN(odim[i], idim[i]); ipos[i] = 0; opos[i] = 0; if (idim[i] != dim[i]) ipos[i] = pos[i]; if (odim[i] != dim[i]) opos[i] = pos[i]; } md_move_block2(D, dim, opos, odim, ostr, optr, ipos, idim, istr, iptr, size); } /** * Copy a block from an array to another array (without strides) * * Block dimensions are min(idim , odim) * * if idim[d] > odim[d], then optr[i] = iptr[pos + i] for 0 <= i < odim[d] * * if idim[d] < odim[d], then optr[pos + i] = iptr[i] for 0 <= i < idim[d] * */ void md_copy_block(unsigned int D, const long pos[D], const long odim[D], void* optr, const long idim[D], const void* iptr, size_t size) { md_copy_block2(D, pos, odim, MD_STRIDES(D, odim, size), optr, idim, MD_STRIDES(D, idim, size), iptr, size); } /** * Resize an array by zero-padding or by truncation at the end. * * optr = [iptr 0 0 0 0] * */ void md_resize(unsigned int D, const long odim[D], void* optr, const long idim[D], const void* iptr, size_t size) { long pos[D]; memset(pos, 0, D * sizeof(long)); md_clear(D, odim, optr, size); md_copy_block(D, pos, odim, optr, idim, iptr, size); } /** * Resize an array by zero-padding or by truncation at both ends symmetrically. * * optr = [0 0 iptr 0 0] * */ void md_resize_center(unsigned int D, const long odim[D], void* optr, const long idim[D], const void* iptr, size_t size) { // the definition of the center position corresponds // to the one used in the FFT. long pos[D]; for (unsigned int i = 0; i < D; i++) pos[i] = labs((odim[i] / 2) - (idim[i] / 2)); md_clear(D, odim, optr, size); md_copy_block(D, pos, odim, optr, idim, iptr, size); } /** * Extract slice from array specified by flags (with strides) * * optr = iptr(pos[0], :, pos[2], :, :) * */ void md_slice2(unsigned int D, unsigned long flags, const long pos[D], const long dim[D], const long ostr[D], void* optr, const long istr[D], const void* iptr, size_t size) { long odim[D]; md_select_dims(D, ~flags, odim, dim); md_copy_block2(D, pos, odim, ostr, optr, dim, istr, iptr, size); } /** * Extract slice from array specified by flags (with strides) * * optr = iptr(pos[0], :, pos[2], :, :) * */ void md_slice(unsigned int D, unsigned long flags, const long pos[D], const long dim[D], void* optr, const void* iptr, size_t size) { long odim[D]; md_select_dims(D, ~flags, odim, dim); md_slice2(D, flags, pos, dim, MD_STRIDES(D, odim, size), optr, MD_STRIDES(D, dim, size), iptr, size); } /** * Permute array (with strides) * * optr[order[i]] = iptr[i] * */ void md_permute2(unsigned int D, const unsigned int order[D], const long odims[D], const long ostr[D], void* optr, const long idims[D], const long istr[D], const void* iptr, size_t size) { unsigned int flags = 0; long ostr2[D]; for (unsigned int i = 0; i < D; i++) { assert(order[i] < D); assert(odims[i] == idims[order[i]]); flags = MD_SET(flags, order[i]); ostr2[order[i]] = ostr[i]; } assert(MD_BIT(D) == flags + 1); md_copy2(D, idims, ostr2, optr, istr, iptr, size); } /** * Permute array (without strides) * * optr[order[i]] = iptr[i] * */ void md_permute(unsigned int D, const unsigned int order[D], const long odims[D], void* optr, const long idims[D], const void* iptr, size_t size) { md_permute2(D, order, odims, MD_STRIDES(D, odims, size), optr, idims, MD_STRIDES(D, idims, size), iptr, size); } /** * Permute dimensions * * */ void md_permute_dims(unsigned int D, const unsigned int order[D], long odims[D], const long idims[D]) { for (unsigned int i = 0; i < D; i++) odims[i] = idims[order[i]]; } static void md_transpose_order(unsigned int D, unsigned int order[D], unsigned int dim1, unsigned int dim2) { assert(dim1 < D); assert(dim2 < D); for (unsigned int i = 0; i < D; i++) order[i] = i; order[dim1] = dim2; order[dim2] = dim1; } /** * Transpose dimensions * * */ void md_transpose_dims(unsigned int D, unsigned int dim1, unsigned int dim2, long odims[D], const long idims[D]) { unsigned int order[D]; md_transpose_order(D, order, dim1, dim2); md_permute_dims(D, order, odims, idims); } /** * Tranpose array (with strides) * * optr[dim2] = iptr[dim1] * * optr[dim1] = iptr[dim2] * */ void md_transpose2(unsigned int D, unsigned int dim1, unsigned int dim2, const long odims[D], const long ostr[D], void* optr, const long idims[D], const long istr[D], const void* iptr, size_t size) { for (unsigned int i = 0; i < D; i++) if ((i != dim1) && (i != dim2)) assert(odims[i] == idims[i]); assert(odims[dim1] == idims[dim2]); assert(odims[dim2] == idims[dim1]); unsigned int order[D]; md_transpose_order(D, order, dim1, dim2); md_permute2(D, order, odims, ostr, optr, idims, istr, iptr, size); } /** * Tranpose array (without strides) * * optr[dim2] = iptr[dim1] * * optr[dim1] = iptr[dim2] * */ void md_transpose(unsigned int D, unsigned int dim1, unsigned int dim2, const long odims[D], void* optr, const long idims[D], const void* iptr, size_t size) { md_transpose2(D, dim1, dim2, odims, MD_STRIDES(D, odims, size), optr, idims, MD_STRIDES(D, idims, size), iptr, size); } static void md_flip_inpl2(unsigned int D, const long dims[D], unsigned long flags, const long str[D], void* ptr, size_t size); /** * Swap input and output while flipping selected dimensions * at the same time. */ void md_swap_flip2(unsigned int D, const long dims[D], unsigned long flags, const long ostr[D], void* optr, const long istr[D], void* iptr, size_t size) { #if 1 int i; for (i = D - 1; i >= 0; i--) if ((1 != dims[i]) && MD_IS_SET(flags, i)) break; if (-1 == i) { md_swap2(D, dims, ostr, optr, istr, iptr, size); return; } assert(1 < dims[i]); assert(ostr[i] != 0); assert(istr[i] != 0); long dims2[D]; md_copy_dims(D, dims2, dims); dims2[i] = dims[i] / 2; long off = (dims[i] + 1) / 2; assert(dims2[i] + off == dims[i]); md_swap_flip2(D, dims2, flags, ostr, optr, istr, iptr + off * istr[i], size); md_swap_flip2(D, dims2, flags, ostr, optr + off * ostr[i], istr, iptr, size); // odd, swap center plane // (we should split in three similar sized chunks instead) dims2[i] = 1; if (1 == dims[i] % 2) md_swap_flip2(D, dims2, flags, ostr, optr + (off - 1) * ostr[i], istr, iptr + (off - 1) * istr[i], size); #else // simpler, but more swaps md_swap2(D, dims, ostr, optr, istr, iptr, size); md_flip_inpl2(D, dims, flags, ostr, optr, size); md_flip_inpl2(D, dims, flags, istr, iptr, size); #endif } /** * Swap input and output while flipping selected dimensions * at the same time. */ void md_swap_flip(unsigned int D, const long dims[D], unsigned long flags, void* optr, void* iptr, size_t size) { long strs[D]; md_calc_strides(D, strs, dims, size); md_swap_flip2(D, dims, flags, strs, optr, strs, iptr, size); } static void md_flip_inpl2(unsigned int D, const long dims[D], unsigned long flags, const long str[D], void* ptr, size_t size) { int i; for (i = D - 1; i >= 0; i--) if ((1 != dims[i]) && MD_IS_SET(flags, i)) break; if (-1 == i) return; assert(1 < dims[i]); assert(str[i] != 0); long dims2[D]; md_copy_dims(D, dims2, dims); dims2[i] = dims[i] / 2; long off = str[i] * (0 + (dims[i] + 1) / 2); md_swap_flip2(D, dims2, flags, str, ptr, str, ptr + off, size); } /** * Flip array (with strides) * * optr[dims[D] - 1 - i] = iptr[i] * */ void md_flip2(unsigned int D, const long dims[D], unsigned long flags, const long ostr[D], void* optr, const long istr[D], const void* iptr, size_t size) { if (optr == iptr) { assert(ostr == istr); md_flip_inpl2(D, dims, flags, ostr, optr, size); return; } long off = 0; long ostr2[D]; for (unsigned int i = 0; i < D; i++) { ostr2[i] = ostr[i]; if (MD_IS_SET(flags, i)) { ostr2[i] = -ostr[i]; off += (dims[i] - 1) * ostr[i]; } } md_copy2(D, dims, ostr2, optr + off, istr, iptr, size); } /** * Flip array (without strides) * * optr[dims[D] - 1 - i] = iptr[i] * */ void md_flip(unsigned int D, const long dims[D], unsigned long flags, void* optr, const void* iptr, size_t size) { long str[D]; md_calc_strides(D, str, dims, size); md_flip2(D, dims, flags, str, optr, str, iptr, size); } bool md_compare2(unsigned int D, const long dims[D], const long str1[D], const void* src1, const long str2[D], const void* src2, size_t size) { __block bool eq = true; const long (*nstr[2])[D] = { (const long (*)[D])str1, (const long (*)[D])str2 }; NESTED(void, nary_cmp, (struct nary_opt_data_s* opt_data, void* ptrs[])) { size_t size2 = size * opt_data->size; bool eq2 = (0 == memcmp(ptrs[0], ptrs[1], size2)); #pragma omp critical eq &= eq2; }; optimized_nop(2, 0u, D, dims, nstr, (void*[2]){ (void*)src1, (void*)src2 }, (size_t[2]){ size, size }, nary_cmp); return eq; } bool md_compare(unsigned int D, const long dims[D], const void* src1, const void* src2, size_t size) { long str[D]; md_calc_strides(D, str, dims, size); return md_compare2(D, dims, str, src1, str, src2, size); } static void md_septrafo_r(unsigned int D, unsigned int R, long dimensions[D], unsigned long flags, const long strides[D], void* ptr, md_trafo_fun_t fun) { if (0 == R--) return; md_septrafo_r(D, R, dimensions, flags, strides, ptr, fun); if (MD_IS_SET(flags, R)) { void* nptr[1] = { ptr }; const long* nstrides[1] = { strides }; long dimsR = dimensions[R]; long strsR = strides[R]; // because of clang dimensions[R] = 1; // we made a copy in md_septrafo2 NESTED(void, nary_septrafo, (void* ptr[])) { fun(dimsR, strsR, ptr[0]); }; //md_nary_parallel(1, D, dimensions, nstrides, nptr, &data, nary_septrafo); md_nary(1, D, dimensions, nstrides, nptr, nary_septrafo); dimensions[R] = dimsR; } } /** * Apply a separable transformation along selected dimensions. * */ void md_septrafo2(unsigned int D, const long dimensions[D], unsigned long flags, const long strides[D], void* ptr, md_trafo_fun_t fun) { long dimcopy[D]; md_copy_dims(D, dimcopy, dimensions); md_septrafo_r(D, D, dimcopy, flags, strides, ptr, fun); } /** * Apply a separable transformation along selected dimensions. * */ void md_septrafo(unsigned int D, const long dims[D], unsigned long flags, void* ptr, size_t size, md_trafo_fun_t fun) { md_septrafo2(D, dims, flags, MD_STRIDES(D, dims, size), ptr, fun); } /** * Copy diagonals from array specified by flags (with strides) * * dst(i, i, :, i, :) = src(i, i, :, i, :) * */ void md_copy_diag2(unsigned int D, const long dims[D], unsigned long flags, const long str1[D], void* dst, const long str2[D], const void* src, size_t size) { long stride1 = 0; long stride2 = 0; long count = -1; for (unsigned int i = 0; i < D; i++) { if (MD_IS_SET(flags, i)) { if (count < 0) count = dims[i]; assert(dims[i] == count); stride1 += str1[i]; stride2 += str2[i]; } } long xdims[D]; md_select_dims(D, ~flags, xdims, dims); for (long i = 0; i < count; i++) md_copy2(D, xdims, str1, dst + i * stride1, str2, src + i * stride2, size); } /** * Copy diagonals from array specified by flags (without strides) * * dst(i ,i ,: ,i , :) = src(i ,i ,: ,i ,:) * */ void md_copy_diag(unsigned int D, const long dims[D], unsigned long flags, void* dst, const void* src, size_t size) { long str[D]; md_calc_strides(D, str, dims, size); md_copy_diag2(D, dims, flags, str, dst, str, src, size); } /** * Fill diagonals specified by flags with value (without strides) * * dst(i, i, :, i, :) = src[0] * */ void md_fill_diag(unsigned int D, const long dims[D], unsigned long flags, void* dst, const void* src, size_t size) { long str2[D]; md_singleton_strides(D, str2); md_copy_diag2(D, dims, flags, MD_STRIDES(D, dims, size), dst, str2, src, size); } static void md_circ_shift_inpl2(unsigned int D, const long dims[D], const long center[D], const long strs[D], void* dst, size_t size) { #if 0 long dims1[D]; long dims2[D]; md_copy_dims(D, dims1, dims); md_copy_dims(D, dims2, dims); unsigned int i; for (i = 0; i < D; i++) { if (0 != center[i]) { dims1[i] = center[i]; dims2[i] = dims[i] - center[i]; break; } } if (i == D) return; long off = strs[i] * center[i]; // cool but slow, instead we want to have a chain of swaps md_flip2(D, dims, MD_BIT(i), strs, dst, strs, dst, size); md_flip2(D, dims1, MD_BIT(i), strs, dst, strs, dst, size); md_flip2(D, dims2, MD_BIT(i), strs, dst + off, strs, dst + off, size); // also not efficient, we want to merge the chain of swaps long center2[D]; md_copy_dims(D, center2, center); center2[i] = 0; md_circ_shift_inpl2(D, dims, center2, strs, dst, size); #else // use tmp for now unsigned int i; for (i = 0; i < D; i++) if (0 != center[i]) break; if (i == D) return; long tmp_strs[D]; md_calc_strides(D, tmp_strs, dims, size); void* tmp = md_alloc_sameplace(D, dims, size, dst); md_copy2(D, dims, tmp_strs, tmp, strs, dst, size); md_circ_shift2(D, dims, center, strs, dst, tmp_strs, tmp, size); md_free(tmp); #endif } /** * Circularly shift array (with strides) * * dst[mod(i + center)] = src[i] * */ void md_circ_shift2(unsigned int D, const long dimensions[D], const long center[D], const long str1[D], void* dst, const long str2[D], const void* src, size_t size) { long pos[D]; for (unsigned int i = 0; i < D; i++) { // FIXME: it would be better to calc modulo pos[i] = center[i]; while (pos[i] < 0) pos[i] += dimensions[i]; } unsigned int i = 0; // FIXME :maybe we shoud search the other way? while ((i < D) && (0 == pos[i])) i++; if (D == i) { md_copy2(D, dimensions, str1, dst, str2, src, size); return; } if (dst == src) { assert(str1 == str2); md_circ_shift_inpl2(D, dimensions, pos, str1, dst, size); return; } long shift = pos[i]; assert(shift != 0); long dim1[D]; long dim2[D]; md_copy_dims(D, dim1, dimensions); md_copy_dims(D, dim2, dimensions); dim1[i] = shift; dim2[i] = dimensions[i] - shift; assert((dim1[i] >= 0) && (dim2[i] >= 0)); pos[i] = 0; //printf("%d: %ld %ld %d\n", i, dim1[i], dim2[i], sizeof(dimensions)); md_circ_shift2(D, dim1, pos, str1, dst, str2, src + dim2[i] * str2[i], size); md_circ_shift2(D, dim2, pos, str1, dst + dim1[i] * str1[i], str2, src, size); } /** * Circularly shift array (without strides) * * dst[mod(i + center)] = src[i] * */ void md_circ_shift(unsigned int D, const long dimensions[D], const long center[D], void* dst, const void* src, size_t size) { long strides[D]; md_calc_strides(D, strides, dimensions, size); md_circ_shift2(D, dimensions, center, strides, dst, strides, src, size); } /** * Circularly extend array (with strides) * */ void md_circ_ext2(unsigned int D, const long dims1[D], const long strs1[D], void* dst, const long dims2[D], const long strs2[D], const void* src, size_t size) { long ext[D]; for (unsigned int i = 0; i < D; i++) { ext[i] = dims1[i] - dims2[i]; assert(ext[i] >= 0); assert(ext[i] <= dims2[i]); } unsigned int i = 0; // FIXME :maybe we shoud search the other way? while ((i < D) && (0 == ext[i])) i++; if (D == i) { md_copy2(D, dims1, strs1, dst, strs2, src, size); return; } long dims1_crop[D]; long dims2_crop[D]; long ext_dims[D]; md_copy_dims(D, dims1_crop, dims1); md_copy_dims(D, dims2_crop, dims2); md_copy_dims(D, ext_dims, dims1); dims1_crop[i] = dims2[i]; dims2_crop[i] = ext[i]; ext_dims[i] = ext[i]; ext[i] = 0; //printf("%d: %ld %ld %d\n", i, dim1[i], dim2[i], sizeof(dimensions)); md_circ_ext2(D, dims1_crop, strs1, dst, dims2, strs2, src, size); md_circ_ext2(D, ext_dims, strs1, dst + dims2[i] * strs1[i], dims2_crop, strs2, src, size); } /** * Circularly extend array (without strides) * */ void md_circ_ext(unsigned int D, const long dims1[D], void* dst, const long dims2[D], const void* src, size_t size) { md_circ_ext2(D, dims1, MD_STRIDES(D, dims1, size), dst, dims2, MD_STRIDES(D, dims2, size), src, size); } /** * Periodically extend array (with strides) * */ void md_periodic2(unsigned int D, const long dims1[D], const long strs1[D], void* dst, const long dims2[D], const long strs2[D], const void* src, size_t size) { long dims1B[2 * D]; long strs1B[2 * D]; long strs2B[2 * D]; for (unsigned int i = 0; i < D; i++) { assert(0 == dims1[i] % dims2[i]); // blocks dims1B[2 * i + 0] = dims2[i]; strs1B[2 * i + 0] = strs1[i]; strs2B[2 * i + 0] = strs2[i]; // periodic copies dims1B[2 * i + 0] = dims1[i] / dims2[i]; strs1B[2 * i + 0] = strs1[i] * dims2[i]; strs2B[2 * i + 0] = 0; } md_copy2(D, dims1B, strs1B, dst, strs2B, src, size); } /** * Periodically extend array (without strides) * */ void md_periodic(unsigned int D, const long dims1[D], void* dst, const long dims2[D], const void* src, size_t size) { md_periodic2(D, dims1, MD_STRIDES(D, dims1, size), dst, dims2, MD_STRIDES(D, dims2, size), src, size); } /** * Allocate CPU memory * * return pointer to CPU memory */ void* md_alloc(unsigned int D, const long dimensions[D], size_t size) { return xmalloc(md_calc_size(D, dimensions) * size); } /** * Allocate CPU memory and clear * * return pointer to CPU memory */ void* md_calloc(unsigned int D, const long dimensions[D], size_t size) { void* ptr = md_alloc(D, dimensions, size); md_clear(D, dimensions, ptr, size); return ptr; } #ifdef USE_CUDA /** * Allocate GPU memory * * return pointer to GPU memory */ void* md_alloc_gpu(unsigned int D, const long dimensions[D], size_t size) { return cuda_malloc(md_calc_size(D, dimensions) * size); } /** * Allocate GPU memory and copy from CPU pointer * * return pointer to GPU memory */ void* md_gpu_move(unsigned int D, const long dims[D], const void* ptr, size_t size) { if (NULL == ptr) return NULL; void* gpu_ptr = md_alloc_gpu(D, dims, size); md_copy(D, dims, gpu_ptr, ptr, size); return gpu_ptr; } #endif /** * Allocate memory on the same device (CPU/GPU) place as ptr * * return pointer to CPU memory if ptr is in CPU or to GPU memory if ptr is in GPU */ void* md_alloc_sameplace(unsigned int D, const long dimensions[D], size_t size, const void* ptr) { #ifdef USE_CUDA return (cuda_ondevice(ptr) ? md_alloc_gpu : md_alloc)(D, dimensions, size); #else assert(0 != ptr); return md_alloc(D, dimensions, size); #endif } /** * Free CPU/GPU memory * */ void md_free(const void* ptr) { #ifdef USE_CUDA if (cuda_ondevice(ptr)) cuda_free((void*)ptr); else #endif xfree(ptr); } bart-0.5.00/src/num/multind.h000066400000000000000000000270071353046746100157560ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __MULTIND_H #define __MULTIND_H 1 #include #include #include #include #include "misc/cppwrap.h" #include "misc/nested.h" typedef void CLOSURE_TYPE(md_nary_fun_t)(void* ptr[]); typedef void CLOSURE_TYPE(md_trafo_fun_t)(long N, long str, void* ptr); typedef void CLOSURE_TYPE(md_loop_fun_t)(const long* pos); extern void md_nary(unsigned int C, unsigned int D, const long dim[__VLA(D)], const long* str[__VLA(C)], void* ptr[__VLA(C)], md_nary_fun_t fun); extern void md_parallel_nary(unsigned int C, unsigned int D, const long dim[__VLA(D)], unsigned long flags, const long* str[__VLA(C)], void* ptr[__VLA(C)], md_nary_fun_t fun); extern void md_parallel_loop(unsigned int D, const long dim[__VLA(D)], unsigned long flags, md_loop_fun_t fun); extern void md_loop(unsigned int D, const long dim[__VLA(D)], md_loop_fun_t fun); extern void md_septrafo2(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, const long strides[__VLA(D)], void* ptr, md_trafo_fun_t fun); extern void md_septrafo(unsigned int D, const long dimensions[__VLA(D)], unsigned long flags, void* ptr, size_t size, md_trafo_fun_t fun); extern void md_clear2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], void* ptr, size_t size); extern void md_clear(unsigned int D, const long dim[__VLA(D)], void* ptr, size_t size); extern void md_swap2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long istr[__VLA(D)], void* iptr, size_t size); extern void md_swap(unsigned int D, const long dim[__VLA(D)], void* optr, void* iptr, size_t size); extern void md_circular_swap2(unsigned M, unsigned int D, const long dims[__VLA(D)], const long* strs[__VLA(M)], void* ptr[__VLA(M)], size_t size); extern void md_circular_swap(unsigned M, unsigned int D, const long dims[__VLA(D)], void* ptr[__VLA(M)], size_t size); extern void md_copy2(unsigned int D, const long dim[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_copy(unsigned int D, const long dim[__VLA(D)], void* optr, const void* iptr, size_t size); extern void md_copy_block2(unsigned int D, const long pos[__VLA(D)], const long odim[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long idim[__VLA(D)], const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_copy_block(unsigned int D, const long pos[__VLA(D)], const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size); extern void md_move_block2(unsigned int D, const long dim[__VLA(D)], const long opos[__VLA(D)], const long odim[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long ipos[__VLA(D)], const long idim[__VLA(D)], const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_move_block(unsigned int D, const long dim[__VLA(D)], const long opos[__VLA(D)], const long odim[__VLA(D)], void* optr, const long ipos[__VLA(D)], const long idim[__VLA(D)], const void* iptr, size_t size); extern void md_resize(unsigned int D, const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size); extern void md_resize_center(unsigned int D, const long odim[__VLA(D)], void* optr, const long idim[__VLA(D)], const void* iptr, size_t size); extern void md_fill2(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], void* ptr, const void* iptr, size_t size); extern void md_fill(unsigned int D, const long dim[__VLA(D)], void* ptr, const void* iptr, size_t size); extern void md_slice2(unsigned int D, unsigned long flags, const long pos[__VLA(D)], const long dim[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_slice(unsigned int D, unsigned long flags, const long pos[__VLA(D)], const long dim[__VLA(D)], void* optr, const void* iptr, size_t size); extern void md_transpose2(unsigned int D, unsigned int dim1, unsigned int dim2, const long odims[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long idims[__VLA(D)], const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_transpose(unsigned int D, unsigned int dim1, unsigned int dim2, const long odims[__VLA(D)], void* optr, const long idims[__VLA(D)], const void* iptr, size_t size); extern void md_permute2(unsigned int D, const unsigned int order[__VLA(D)], const long odims[__VLA(D)], const long ostr[__VLA(D)], void* optr, const long idims[__VLA(D)], const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_permute(unsigned int D, const unsigned int order[__VLA(D)], const long odims[__VLA(D)], void* optr, const long idims[__VLA(D)], const void* iptr, size_t size); extern void md_flip2(unsigned int D, const long dims[__VLA(D)], unsigned long flags, const long ostr[__VLA(D)], void* optr, const long istr[__VLA(D)], const void* iptr, size_t size); extern void md_flip(unsigned int D, const long dims[__VLA(D)], unsigned long flags, void* optr, const void* iptr, size_t size); extern void md_swap_flip2(unsigned int D, const long dims[__VLA(D)], unsigned long flags, const long ostr[__VLA(D)], void* optr, const long istr[__VLA(D)], void* iptr, size_t size); extern void md_swap_flip(unsigned int D, const long dims[__VLA(D)], unsigned long flags, void* optr, void* iptr, size_t size); extern void md_copy_diag2(unsigned int D, const long dims[__VLA(D)], unsigned long flags, const long str1[__VLA(D)], void* dst, const long str2[__VLA(D)], const void* src, size_t size); extern void md_copy_diag(unsigned int D, const long dims[__VLA(D)], unsigned long flags, void* dst, const void* src, size_t size); extern void md_fill_diag(unsigned int D, const long dims[__VLA(D)], unsigned long flags, void* dst, const void* src, size_t size); extern void md_circ_shift2(unsigned int D, const long dim[__VLA(D)], const long center[__VLA(D)], const long str1[__VLA(D)], void* dst, const long str2[__VLA(D)], const void* src, size_t size); extern void md_circ_shift(unsigned int D, const long dim[__VLA(D)], const long center[__VLA(D)], void* dst, const void* src, size_t size); extern void md_circ_ext2(unsigned int D, const long dims1[__VLA(D)], const long strs1[__VLA(D)], void* dst, const long dims2[__VLA(D)], const long strs2[__VLA(D)], const void* src, size_t size); extern void md_circ_ext(unsigned int D, const long dims1[__VLA(D)], void* dst, const long dims2[__VLA(D)], const void* src, size_t size); extern void md_periodic2(unsigned int D, const long dims1[__VLA(D)], const long strs1[__VLA(D)], void* dst, const long dims2[__VLA(D)], const long strs2[__VLA(D)], const void* src, size_t size); extern void md_periodic(unsigned int D, const long dims1[__VLA(D)], void* dst, const long dims2[__VLA(D)], const void* src, size_t size); extern _Bool md_compare2(unsigned int D, const long dims[__VLA(D)], const long str1[__VLA(D)], const void* src1, const long str2[__VLA(D)], const void* src2, size_t size); extern _Bool md_compare(unsigned int D, const long dims[__VLA(D)], const void* src1, const void* src2, size_t size); typedef void* (*md_alloc_fun_t)(unsigned int D, const long dimensions[__VLA(D)], size_t size); extern void* md_alloc(unsigned int D, const long dimensions[__VLA(D)], size_t size); extern void* md_calloc(unsigned int D, const long dimensions[__VLA(D)], size_t size); #ifdef USE_CUDA extern void* md_alloc_gpu(unsigned int D, const long dimensions[__VLA(D)], size_t size); extern void* md_gpu_move(unsigned int D, const long dims[__VLA(D)], const void* ptr, size_t size); #endif extern void* md_alloc_sameplace(unsigned int D, const long dimensions[__VLA(D)], size_t size, const void* ptr); extern void md_free(const void* p); extern long md_calc_size(unsigned int D, const long dimensions[__VLA(D)]); extern long* md_calc_strides(unsigned int D, long str[__VLA(D)], const long dim[__VLA(D)], size_t size); extern long md_calc_offset(unsigned int D, const long strides[__VLA(D)], const long position[__VLA(D)]); extern unsigned int md_calc_blockdim(unsigned int D, const long dim[__VLA(D)], const long str[__VLA(D)], size_t size); extern void md_select_dims(unsigned int D, unsigned long flags, long odims[__VLA(D)], const long idims[__VLA(D)]); extern void md_copy_dims(unsigned int D, long odims[__VLA(D)], const long idims[__VLA(D)]); extern void md_copy_strides(unsigned int D, long odims[__VLA(D)], const long idims[__VLA(D)]); extern void md_merge_dims(unsigned int D, long odims[__VLA(D)], const long dims1[__VLA(D)], const long dims2[__VLA(D)]); extern _Bool md_check_compat(unsigned int D, unsigned long flags, const long dim1[__VLA(D)], const long dim2[__VLA(D)]); extern _Bool md_check_bounds(unsigned int D, unsigned long flags, const long dim1[__VLA(D)], const long dim2[__VLA(D)]); extern void md_singleton_dims(unsigned int D, long dims[__VLA(D)]); extern void md_singleton_strides(unsigned int D, long strs[__VLA(D)]); extern void md_set_dims(unsigned int D, long dims[__VLA(D)], long val); extern void md_min_dims(unsigned int D, unsigned long flags, long odims[__VLA(D)], const long idims1[__VLA(D)], const long idims2[__VLA(D)]); extern void md_max_dims(unsigned int D, unsigned long flags, long odims[__VLA(D)], const long idims1[__VLA(D)], const long idims2[__VLA(D)]); extern _Bool md_is_index(unsigned int D, const long pos[__VLA(D)], const long dims[__VLA(D)]); extern _Bool md_check_dimensions(unsigned int N, const long dims[__VLA(N)], unsigned int flags); extern void md_permute_dims(unsigned int D, const unsigned int order[__VLA(D)], long odims[__VLA(D)], const long idims[__VLA(D)]); extern void md_transpose_dims(unsigned int D, unsigned int dim1, unsigned int dim2, long odims[__VLA(D)], const long idims[__VLA(D)]); extern _Bool md_next(unsigned int D, const long dims[__VLA(D)], unsigned long flags, long pos[__VLA(D)]); extern unsigned long md_nontriv_dims(unsigned int D, const long dims[__VLA(D)]); extern unsigned long md_nontriv_strides(unsigned int D, const long dims[__VLA(D)]); #define MD_INIT_ARRAY(x, y) { [ 0 ... ((x) - 1) ] = (y) } #define MD_MAKE_ARRAY(T, ...) ((T[]){ __VA_ARGS__ }) #define MD_DIMS(...) MD_MAKE_ARRAY(long, __VA_ARGS__) #define MD_BIT(x) (1ul << (x)) #define MD_IS_SET(x, y) ((x) & MD_BIT(y)) #define MD_CLEAR(x, y) ((x) & ~MD_BIT(y)) #define MD_SET(x, y) ((x) | MD_BIT(y)) #define MD_CAST_ARRAY2_PTR(T, N, dims, x, a, b) \ (assert(((a) < (b)) && !md_check_dimensions((N), (dims), (1 << (a)) | (1 << (b)))), \ (T (*)[(dims)[b]][(dims)[a]])(x)) #define MD_CAST_ARRAY3_PTR(T, N, dims, x, a, b, c) \ (assert(((a) < (b)) && ((b) < (c)) && !md_check_dimensions((N), (dims), (1 << (a)) | (1 << (b) | (1 << (c))))), \ (T (*)[(dims)[c]][(dims)[b]][(dims)[a]])(x)) #define MD_CAST_ARRAY2(T, N, dims, x, a, b) (*MD_CAST_ARRAY2_PTR(T, N, dims, x, a, b)) #define MD_CAST_ARRAY3(T, N, dims, x, a, b, c) (*MD_CAST_ARRAY3_PTR(T, N, dims, x, a, b, c)) #define MD_ACCESS(N, strs, pos, x) ((x)[md_calc_offset((N), (strs), (pos)) / sizeof((x)[0])]) #define MD_STRIDES(N, dims, elsize) (md_calc_strides(N, alloca(N * sizeof(long)), dims, elsize)) #define MD_SINGLETON_DIMS(N) \ ({ \ unsigned int _N = (N); \ long* _dims = alloca(_N * sizeof(long)); \ md_singleton_dims(_N, _dims); \ _dims; \ }) #define MD_SINGLETON_STRS(N) \ ({ \ unsigned int _N = (N); \ long* _dims = alloca(_N * sizeof(long)); \ md_singleton_strides(_N, _dims); \ _dims; \ }) #include "misc/cppwrap.h" #endif // __MULTIND_H bart-0.5.00/src/num/ode.c000066400000000000000000000152311353046746100150400ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include //sqrt // #include "iter/vec_iter.h" #include "ode.h" static void vec_saxpy(unsigned int N, float dst[N], const float a[N], float alpha, const float b[N]) { for (unsigned int i = 0; i < N; i++) dst[i] = a[i] + alpha * b[i]; } static void vec_copy(unsigned N, float dst[N], const float src[N]) { vec_saxpy(N, dst, src, 0., src); } static float vec_sdot(unsigned int N, const float a[N], const float b[N]) { float ret = 0.; for (unsigned int i = 0; i < N; i++) ret += a[i] * b[i]; return ret; } static float vec_norm(unsigned int N, const float x[N]) { return sqrtf(vec_sdot(N, x, x)); } #define tridiag(s) (s * (s + 1) / 2) static void runga_kutta_step(float h, unsigned int s, const float a[tridiag(s)], const float b[s], const float c[s - 1], unsigned int N, unsigned int K, float k[K][N], float ynp[N], float tmp[N], float tn, const float yn[N], void* data, void (*f)(void* data, float* out, float t, const float* yn)) { vec_saxpy(N, ynp, yn, h * b[0], k[0]); for (unsigned int l = 0, t = 1; t < s; t++) { vec_copy(N, tmp, yn); for (unsigned int r = 0; r < t; r++, l++) vec_saxpy(N, tmp, tmp, h * a[l], k[r % K]); f(data, k[t % K], tn + h * c[t - 1], tmp); vec_saxpy(N, ynp, ynp, h * b[t], k[t % K]); } } // Runga-Kutta 4 void rk4_step(float h, unsigned int N, float ynp[N], float tn, const float yn[N], void* data, void (*f)(void* data, float* out, float t, const float* yn)) { const float c[3] = { 0.5, 0.5, 1. }; const float a[6] = { 0.5, 0.0, 0.5, 0.0, 0.0, 1.0, }; const float b[4] = { 1. / 6., 1. / 3., 1. / 3., 1. / 6. }; float k[1][N]; // K = 1 because only diagonal elements are used f(data, k[0], tn, yn); float tmp[N]; runga_kutta_step(h, 4, a, b, c, N, 1, k, ynp, tmp, tn, yn, data, f); } /* * Dormand JR, Prince PJ. A family of embedded Runge-Kutta formulae, * Journal of Computational and Applied Mathematics 6:19-26 (1980). */ void dormand_prince_step(float h, unsigned int N, float ynp[N], float tn, const float yn[N], void* data, void (*f)(void* data, float* out, float t, const float* yn)) { const float c[6] = { 1. / 5., 3. / 10., 4. / 5., 8. / 9., 1., 1. }; const float a[tridiag(7)] = { 1. / 5., 3. / 40., 9. / 40., 44. / 45., -56. / 15., 32. / 9., 19372. / 6561., -25360. / 2187., 64448. / 6561., -212. / 729., 9017. / 3168., -355. / 33., 46732. / 5247., 49. / 176., -5103. / 18656., 35. / 384., 0., 500. / 1113., 125. / 192., -2187. / 6784., 11. / 84., }; const float b[7] = { 5179. / 57600., 0., 7571. / 16695., 393. / 640., -92097. / 339200., 187. / 2100., 1. / 40. }; float k[6][N]; f(data, k[0], tn, yn); float tmp[N]; runga_kutta_step(h, 7, a, b, c, N, 6, k, ynp, tmp, tn, yn, data, f); } float dormand_prince_scale(float tol, float err) { #if 0 float sc = 0.75 * powf(tol / err, 1. / 5.); return (sc < 2.) ? sc : 2.; #else float sc = 1.25 * powf(err / tol, 1. / 5.); return 1. / ((sc > 1. / 2.) ? sc : (1. / 2.)); #endif } float dormand_prince_step2(float h, unsigned int N, float ynp[N], float tn, const float yn[N], float k[6][N], void* data, void (*f)(void* data, float* out, float t, const float* yn)) { const float c[6] = { 1. / 5., 3. / 10., 4. / 5., 8. / 9., 1., 1. }; const float a[tridiag(7)] = { 1. / 5., 3. / 40., 9. / 40., 44. / 45., -56. / 15., 32. / 9., 19372. / 6561., -25360. / 2187., 64448. / 6561., -212. / 729., 9017. / 3168., -355. / 33., 46732. / 5247., 49. / 176., -5103. / 18656., 35. / 384., 0., 500. / 1113., 125. / 192., -2187. / 6784., 11. / 84., }; const float b[7] = { 5179. / 57600., 0., 7571. / 16695., 393. / 640., -92097. / 339200., 187. / 2100., 1. / 40. }; float tmp[N]; runga_kutta_step(h, 7, a, b, c, N, 6, k, ynp, tmp, tn, yn, data, f); vec_saxpy(N, tmp, tmp, -1., ynp); return vec_norm(N, tmp); } void ode_interval(float h, float tol, unsigned int N, float x[N], float st, float end, void* data, void (*f)(void* data, float* out, float t, const float* yn)) { float k[6][N]; f(data, k[0], st, x); if (h > end - st) h = end - st; for (float t = st; t < end; ) { float ynp[N]; repeat: ; float err = dormand_prince_step2(h, N, ynp, t, x, k, data, f); float h_new = h * dormand_prince_scale(tol, err); if (err > tol) { h = h_new; f(data, k[0], t, x); // recreate correct k[0] which has been overwritten goto repeat; } t += h; h = h_new; if (t + h > end) h = end - t; for (unsigned int i = 0; i < N; i++) x[i] = ynp[i]; } } struct ode_matrix_s { unsigned int N; const float* matrix; }; static void ode_matrix_fun(void* _data, float* x, float t, const float* in) { struct ode_matrix_s* data = _data; (void)t; unsigned int N = data->N; for (unsigned int i = 0; i < N; i++) { x[i] = 0.; for (unsigned int j = 0; j < N; j++) x[i] += (*(const float(*)[N][N])data->matrix)[i][j] * in[j]; } } void ode_matrix_interval(float h, float tol, unsigned int N, float x[N], float st, float end, const float matrix[N][N]) { struct ode_matrix_s data = { N, &matrix[0][0] }; ode_interval(h, tol, N, x, st, end, &data, ode_matrix_fun); } // the direct method for sensitivity analysis // ode: d/dt y_i = f_i(y, t, p_j), y_i(0) = a_i // d/dp_j y_i(0) = ... // d/dt d/dp_j y_i(t) = d/dp_j f_i(y, t, p) = \sum_k d/dy_k f_i(y, t, p) * dy_k/dp_j + df_i / dp_j struct seq_data { unsigned int N; unsigned int P; void* data; void (*f)(void* data, float* out, float t, const float* yn); void (*pdy)(void* data, float* out, float t, const float* yn); void (*pdp)(void* data, float* out, float t, const float* yn); }; static void seq(void* _data, float* out, float t, const float* yn) { struct seq_data* data = _data; int N = data->N; int P = data->P; data->f(data->data, out, t, yn); float dy[N][N]; data->pdy(data->data, &dy[0][0], t, yn); float dp[P][N]; data->pdp(data->data, &dp[0][0], t, yn); for (int i = 0; i < P; i++) { for (int j = 0; j < N; j++) { out[(1 + i) * N + j] = 0.; for (int k = 0; k < N; k++) out[(1 + i) * N + j] += dy[k][j] * yn[(1 + i) * N + k]; out[(1 + i) * N + j] += dp[i][j]; } } } void ode_direct_sa(float h, float tol, unsigned int N, unsigned int P, float x[P + 1][N], float st, float end, void* data, void (*f)(void* data, float* out, float t, const float* yn), void (*pdy)(void* data, float* out, float t, const float* yn), void (*pdp)(void* data, float* out, float t, const float* yn)) { struct seq_data data2 = { N, P, data, f, pdy, pdp }; ode_interval(h, tol, N * (1 + P), &x[0][0], st, end, &data2, seq); } bart-0.5.00/src/num/ode.h000066400000000000000000000022751353046746100150510ustar00rootroot00000000000000 extern void rk4_step(float h, unsigned int N, float ynp[N], float tn, const float yn[N], void* data, void (*f)(void* data, float* out, float t, const float* yn)); extern void dormand_prince_step(float h, unsigned int N, float ynp[N], float tn, const float yn[N], void* data, void (*f)(void* data, float* out, float t, const float* yn)); extern float dormand_prince_step2(float h, unsigned int N, float ynp[N], float tn, const float yn[N], float tmp[6][N], void* data, void (*f)(void* data, float* out, float t, const float* yn)); extern float dormand_prince_scale(float tol, float err); extern void ode_interval(float h, float tol, unsigned int N, float x[N], float st, float end, void* data, void (*f)(void* data, float* out, float t, const float* yn)); extern void ode_matrix_interval(float h, float tol, unsigned int N, float x[N], float st, float end, const float matrix[N][N]); extern void ode_direct_sa(float h, float tol, unsigned int N, unsigned int P, float x[P + 1][N], float st, float end, void* data, void (*f)(void* data, float* out, float t, const float* yn), void (*pdy)(void* data, float* out, float t, const float* yn), void (*pdp)(void* data, float* out, float t, const float* yn)); bart-0.5.00/src/num/ops.c000066400000000000000000001076431353046746100151030ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2019 Martin Uecker * 2014 Jonathan Tamir * 2014 Frank Ong * * operator expressions working on multi-dimensional arrays */ #include #include #include #include #include #include #include "num/multind.h" #include "num/iovec.h" #include "misc/misc.h" #include "misc/types.h" #include "misc/debug.h" #include "misc/shrdptr.h" #include "misc/nested.h" #ifdef USE_CUDA #ifdef _OPENMP #include #endif #include "num/gpuops.h" #endif #include "ops.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif #ifndef FL_SIZE #define FL_SIZE sizeof(float) #endif struct operator_s { unsigned int N; unsigned int io_flags; const struct iovec_s** domain; operator_data_t* data; void (*apply)(const operator_data_t* data, unsigned int N, void* args[N]); void (*del)(const operator_data_t* data); struct shared_obj_s sptr; }; static void operator_del(const struct shared_obj_s* sptr) { const struct operator_s* x = CONTAINER_OF(sptr, const struct operator_s, sptr); if (NULL != x->del) x->del(x->data); for (unsigned int i = 0; i < x->N; i++) iovec_free(x->domain[i]); xfree(x->domain); xfree(x); } /** * Create an operator (with strides) */ const struct operator_s* operator_generic_create2(unsigned int N, unsigned int io_flags, const unsigned int D[N], const long* dims[N], const long* strs[N], operator_data_t* data, operator_fun_t apply, operator_del_t del) { PTR_ALLOC(struct operator_s, op); PTR_ALLOC(const struct iovec_s*[N], dom); for (unsigned int i = 0; i < N; i++) (*dom)[i] = iovec_create2(D[i], dims[i], strs[i], CFL_SIZE); op->N = N; op->io_flags = io_flags; op->domain = *PTR_PASS(dom); op->data = data; op->apply = apply; op->del = del; shared_obj_init(&op->sptr, operator_del); return PTR_PASS(op); } /** * Create an operator (without strides) */ const struct operator_s* operator_generic_create(unsigned int N, unsigned int io_flags, const unsigned int D[N], const long* dims[N], operator_data_t* data, operator_fun_t apply, operator_del_t del) { const long* strs[N]; for (unsigned int i = 0; i < N; i++) strs[i] = MD_STRIDES(D[i], dims[i], CFL_SIZE); return operator_generic_create2(N, io_flags, D, dims, strs, data, apply, del); } /** * Create an operator (with strides) */ const struct operator_s* operator_create2(unsigned int ON, const long out_dims[ON], const long out_strs[ON], unsigned int IN, const long in_dims[IN], const long in_strs[IN], operator_data_t* data, operator_fun_t apply, operator_del_t del) { return operator_generic_create2(2, MD_BIT(0), (unsigned int[2]){ ON, IN }, (const long* [2]){ out_dims, in_dims }, (const long* [2]){ out_strs, in_strs }, data, apply, del); } /** * Create an operator (without strides) * * @param ON number of output dimensions * @param out_dims dimensions of output * @param IN number of input dimensions * @param in_dims dimensions of input * @param data data for applying the operation * @param apply function that applies the operation * @param del function that frees the data */ const struct operator_s* operator_create(unsigned int ON, const long out_dims[ON], unsigned int IN, const long in_dims[IN], operator_data_t* data, operator_fun_t apply, operator_del_t del) { return operator_create2(ON, out_dims, MD_STRIDES(ON, out_dims, CFL_SIZE), IN, in_dims, MD_STRIDES(IN, in_dims, CFL_SIZE), data, apply, del); } /** * Increment the reference count of an operator * * @param x operator */ const struct operator_s* operator_ref(const struct operator_s* x) { if (NULL != x) shared_obj_ref(&x->sptr); return x; } /** * Decrement the reference count of an operator * * @param x operator */ const struct operator_s* operator_unref(const struct operator_s* x) { if (NULL != x) shared_obj_unref(&x->sptr); return x; } /** * Return the data of the associated operator * * @param x operator */ operator_data_t* operator_get_data(const struct operator_s* x) { return x->data; } /** * Free the operator struct * Note: also frees the data if the operator's reference count is zero * * @param x operator */ void operator_free(const struct operator_s* x) { if (NULL == x) return; shared_obj_destroy(&x->sptr); } /** * Return the number of args * * @param op operator */ unsigned int operator_nr_args(const struct operator_s* op) { return op->N; } /** * Return the number of input args * * @param op operator */ unsigned int operator_nr_in_args(const struct operator_s* op) { return operator_nr_args(op) - operator_nr_out_args(op); } /** * Return the number of input args * * @param op operator */ unsigned int operator_nr_out_args(const struct operator_s* op) { unsigned int N = operator_nr_args(op); unsigned int O = 0; for (unsigned int i = 0; i < N; i++) if (MD_IS_SET(op->io_flags, i)) O++; return O; } unsigned int operator_ioflags(const struct operator_s* op) { return op->io_flags; } /** * Return the iovec of arg n * * @param op operator * @param n arg number */ const struct iovec_s* operator_arg_domain(const struct operator_s* op, unsigned int n) { assert(n < op->N); return op->domain[n]; } /** * Return the dimensions and strides of the domain of an operator * * @param op operator */ const struct iovec_s* operator_domain(const struct operator_s* op) { assert(2 == op->N); assert(1u == op->io_flags); return operator_arg_domain(op, 1); } /** * Return the dimensions and strides of the codomain of an operator * * @param op operator */ const struct iovec_s* operator_codomain(const struct operator_s* op) { assert(2 == op->N); assert(1u == op->io_flags); return operator_arg_domain(op, 0); } struct identity_s { INTERFACE(operator_data_t); const struct iovec_s* domain; const struct iovec_s* codomain; }; static DEF_TYPEID(identity_s); static void identity_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { const auto d = CAST_DOWN(identity_s, _data); assert(2 == N); md_copy2(d->domain->N, d->domain->dims, d->codomain->strs, args[0], d->domain->strs, args[1], d->domain->size); } static void identity_free(const operator_data_t* _data) { const auto d = CAST_DOWN(identity_s, _data); iovec_free(d->domain); iovec_free(d->codomain); xfree(d); } const struct operator_s* operator_identity_create2(unsigned int N, const long dims[N], const long ostrs[N], const long istrs[N]) { PTR_ALLOC(struct identity_s, data); SET_TYPEID(identity_s, data); data->domain = iovec_create2(N, dims, istrs, CFL_SIZE); data->codomain = iovec_create2(N, dims, ostrs, CFL_SIZE); return operator_create2(N, dims, ostrs, N, dims, istrs, CAST_UP(PTR_PASS(data)), identity_apply, identity_free); } /** * Create an Identity operator: I x * @param N number of dimensions * @param dims dimensions of input (domain) */ const struct operator_s* operator_identity_create(unsigned int N, const long dims[N]) { long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); return operator_identity_create2(N, dims, strs, strs); } struct zero_s { INTERFACE(operator_data_t); const struct iovec_s* codomain; }; static DEF_TYPEID(zero_s); static void zero_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { auto d = CAST_DOWN(zero_s, _data); assert(1 == N); md_clear2(d->codomain->N, d->codomain->dims, d->codomain->strs, args[0], d->codomain->size); } static void zero_free(const operator_data_t* _data) { auto d = CAST_DOWN(zero_s, _data); iovec_free(d->codomain); xfree(d); } const struct operator_s* operator_zero_create2(unsigned int N, const long dims[N], const long strs[N]) { PTR_ALLOC(struct zero_s, data); SET_TYPEID(zero_s, data); data->codomain = iovec_create2(N, dims, strs, CFL_SIZE); return operator_generic_create2(1, 1u, (unsigned int[1]){ N }, (const long*[1]){ dims }, (const long*[2]){ strs }, CAST_UP(PTR_PASS(data)), zero_apply, zero_free); } const struct operator_s* operator_zero_create(unsigned int N, const long dims[N]) { return operator_zero_create2(N, dims, MD_STRIDES(N, dims, CFL_SIZE)); } struct null_s { INTERFACE(operator_data_t); }; static DEF_TYPEID(null_s); static void null_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { UNUSED(_data); assert(1 == N); UNUSED(args[0]); } static void null_free(const operator_data_t* _data) { xfree(CAST_DOWN(null_s, _data)); } const struct operator_s* operator_null_create2(unsigned int N, const long dims[N], const long strs[N]) { PTR_ALLOC(struct null_s, data); SET_TYPEID(null_s, data); return operator_generic_create2(1, 0u, (unsigned int[1]){ N }, (const long*[1]){ dims }, (const long*[2]){ strs }, CAST_UP(PTR_PASS(data)), null_apply, null_free); } const struct operator_s* operator_null_create(unsigned int N, const long dims[N]) { return operator_null_create2(N, dims, MD_STRIDES(N, dims, CFL_SIZE)); } /** * Create a new operator that first applies a, then applies b: * c(x) = b(a(x)) */ const struct operator_s* operator_chain(const struct operator_s* a, const struct operator_s* b) { assert((2 == a->N) && (2 == b->N)); // check compatibility debug_printf(DP_DEBUG4, "operator chain:\n"); debug_print_dims(DP_DEBUG4, a->domain[0]->N, a->domain[0]->dims); debug_print_dims(DP_DEBUG4, b->domain[1]->N, b->domain[1]->dims); debug_printf(DP_DEBUG4, "IO Flags: %d %d\n", a->io_flags, b->io_flags); assert((MD_BIT(0) == a->io_flags) && (MD_BIT(0) == b->io_flags)); assert(a->domain[0]->N == b->domain[1]->N); assert(md_calc_size(a->domain[0]->N, a->domain[0]->dims) == md_calc_size(b->domain[1]->N, b->domain[1]->dims)); // check whether intermediate storage can be simple assert(a->domain[0]->N == md_calc_blockdim(a->domain[0]->N, a->domain[0]->dims, a->domain[0]->strs, a->domain[0]->size)); assert(b->domain[1]->N == md_calc_blockdim(b->domain[1]->N, b->domain[1]->dims, b->domain[1]->strs, b->domain[1]->size)); auto op = operator_combi_create(2, MAKE_ARRAY(b, a)); assert((MD_BIT(0) | MD_BIT(2)) == op->io_flags); auto op2 = operator_link_create(op, 2, 1); operator_free(op); return op2; } const struct operator_s* operator_chainN(unsigned int N, const struct operator_s* ops[N]) { assert(N > 0); const struct operator_s* s = operator_identity_create(ops[0]->domain[0]->N, ops[0]->domain[1]->dims); for (unsigned int i = 0; i < N; i++) s = operator_chain(OP_PASS(s), ops[i]); return s; } void operator_generic_apply_unchecked(const struct operator_s* op, unsigned int N, void* args[N]) { assert(op->N == N); debug_trace("ENTER %p\n", op->apply); op->apply(op->data, N, args); debug_trace("LEAVE %p\n", op->apply); } void operator_apply_unchecked(const struct operator_s* op, complex float* dst, const complex float* src) { assert(1u == op->io_flags); operator_generic_apply_unchecked(op, 2, (void*[2]){ (void*)dst, (void*)src }); } void operator_apply2(const struct operator_s* op, unsigned int ON, const long odims[ON], const long ostrs[ON], complex float* dst, const long IN, const long idims[IN], const long istrs[ON], const complex float* src) { assert(2 == op->N); assert(iovec_check(op->domain[1], IN, idims, istrs)); assert(iovec_check(op->domain[0], ON, odims, ostrs)); operator_apply_unchecked(op, dst, src); } void operator_apply(const struct operator_s* op, unsigned int ON, const long odims[ON], complex float* dst, const long IN, const long idims[IN], const complex float* src) { operator_apply2(op, ON, odims, MD_STRIDES(ON, odims, CFL_SIZE), dst, IN, idims, MD_STRIDES(IN, idims, CFL_SIZE), src); } struct attach_data_s { INTERFACE(operator_data_t); const struct operator_s* op; void* ptr; void (*del)(const void* ptr); }; static DEF_TYPEID(attach_data_s); static void attach_fun(const operator_data_t* _data, unsigned int N, void* args[N]) { const auto op = CAST_DOWN(attach_data_s, _data)->op; operator_generic_apply_unchecked(op, N, args); } static void attach_del(const operator_data_t* _data) { const auto data = CAST_DOWN(attach_data_s, _data); operator_free(data->op); data->del(data->ptr); xfree(data); } const struct operator_s* operator_attach(const struct operator_s* op, void* ptr, void (*del)(const void* ptr)) { unsigned int N = operator_nr_args(op); unsigned int D[N]; const long* dims[N]; const long* strs[N]; for (unsigned int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); D[i] = io->N; dims[i] = io->dims; strs[i] = io->strs; } // op = operator_ref(op); PTR_ALLOC(struct attach_data_s, data); SET_TYPEID(attach_data_s, data); data->op = op; data->ptr = ptr; data->del = del; return operator_generic_create2(N, op->io_flags, D, dims, strs, CAST_UP(PTR_PASS(data)), attach_fun, attach_del); } struct op_bind_s { INTERFACE(operator_data_t); unsigned int D; unsigned int arg; const struct operator_s* op; void* ptr; }; static DEF_TYPEID(op_bind_s); static void op_bind_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { const auto data = CAST_DOWN(op_bind_s, _data); assert(data->D == N + 1); void* n_args[N + 1]; for (unsigned int i = 0, j = 0; i < N; i++, j++) { // insert bound argument if (data->arg == i) n_args[j++] = data->ptr; n_args[j] = args[i]; } operator_generic_apply_unchecked(data->op, N + 1, n_args); } static void op_bind_del(const operator_data_t* _data) { const auto data = CAST_DOWN(op_bind_s, _data); operator_free(data->op); xfree(data); } /** * Create a new operator that binds argument 'arg'. */ const struct operator_s* operator_bind2(const struct operator_s* op, unsigned int arg, unsigned int N, const long dims[N], const long strs[N], void* ptr) { unsigned int D = operator_nr_args(op); assert(arg < D); assert(!MD_IS_SET(op->io_flags, arg)); assert(iovec_check(operator_arg_domain(op, arg), N, dims, strs)); unsigned int nn[D - 1]; const long* ndims[D - 1]; const long* nstrs[D - 1]; unsigned int n_flags = 0u; for (unsigned int i = 0, j = 0; i < D; i++) { if (arg == i) continue; nn[j] = operator_arg_domain(op, i)->N; ndims[j] = operator_arg_domain(op, i)->dims; nstrs[j] = operator_arg_domain(op, i)->strs; if (MD_IS_SET(op->io_flags, i)) n_flags |= MD_BIT(j); j++; } PTR_ALLOC(struct op_bind_s, data); SET_TYPEID(op_bind_s, data); data->D = D; data->arg = arg; data->ptr = ptr; data->op = op; return operator_generic_create2(D - 1, n_flags, nn, ndims, nstrs, CAST_UP(PTR_PASS(data)), op_bind_apply, op_bind_del); } struct op_loop_s { INTERFACE(operator_data_t); unsigned int N; unsigned int D; const long** strs; const long** dims; const long* dims0; const struct operator_s* op; unsigned int parallel; bool gpu; }; static DEF_TYPEID(op_loop_s); static void op_loop_del(const operator_data_t* _data) { const auto data = CAST_DOWN(op_loop_s, _data); operator_free(data->op); for (unsigned int i = 0; i < data->N; i++) { xfree(data->dims[i]); xfree(data->strs[i]); } xfree(data->strs); xfree(data->dims); xfree(data->dims0); xfree(data); } static void op_loop_fun(const operator_data_t* _data, unsigned int N, void* args[N]) { const auto data = CAST_DOWN(op_loop_s, _data); assert(N == data->N); if (data->gpu) { #if defined(USE_CUDA) && defined(_OPENMP) int nr_cuda_devices = cuda_devices(); omp_set_num_threads(nr_cuda_devices * 2); // fft_set_num_threads(1); #else assert(0); #endif } extern bool num_auto_parallelize; bool ap_save = num_auto_parallelize; num_auto_parallelize = false; NESTED(void, op_loop_nary, (void* ptr[])) { operator_generic_apply_unchecked(data->op, data->N, ptr); }; md_parallel_nary(N, data->D, data->dims0, data->parallel, data->strs, args, op_loop_nary); num_auto_parallelize = ap_save; } static void merge_dims(unsigned int D, long odims[D], const long idims1[D], const long idims2[D]) { md_copy_dims(D, odims, idims1); for (unsigned int i = 0; i < D; i++) { assert((1 == odims[i]) | (1 == idims2[i])); if (1 == odims[i]) odims[i] = idims2[i]; } } const struct operator_s* (operator_loop_parallel2)(unsigned int N, const unsigned int D, const long dims[D], const long (*strs)[D], const struct operator_s* op, unsigned int flags, bool gpu) { assert(N == operator_nr_args(op)); unsigned int D2[N]; PTR_ALLOC(long[D], dims0); md_copy_dims(D, *dims0, dims); PTR_ALLOC(const long*[N], dims2); PTR_ALLOC(const long*[N], strs2); // TODO: we should have a flag and ignore args with flag for (unsigned int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); assert(D == io->N); for (unsigned int j = 0; j < D; j++) { assert((0 == io->strs[j]) || (io->strs[j] == strs[i][j])); assert((1 == io->dims[j]) == (0 == io->strs[j])); } D2[i] = D; PTR_ALLOC(long[D], tdims); merge_dims(D, *tdims, dims, io->dims); PTR_ALLOC(long[D], tstrs); md_copy_strides(D, *tstrs, strs[i]); (*dims2)[i] = *PTR_PASS(tdims); (*strs2)[i] = *PTR_PASS(tstrs); } PTR_ALLOC(struct op_loop_s, data); SET_TYPEID(op_loop_s, data); data->N = N; data->D = D; data->op = op; data->dims0 = *PTR_PASS(dims0); data->dims = */*PTR_PASS*/(dims2); data->strs = */*PTR_PASS*/(strs2); data->parallel = flags; data->gpu = gpu; const struct operator_s* rop = operator_generic_create2(N, op->io_flags, D2, *dims2, *strs2, CAST_UP(PTR_PASS(data)), op_loop_fun, op_loop_del); PTR_PASS(dims2); PTR_PASS(strs2); return rop; } const struct operator_s* (operator_loop2)(unsigned int N, const unsigned int D, const long dims[D], const long (*strs)[D], const struct operator_s* op) { return operator_loop_parallel2(N, D, dims, strs, op, 0u, false); } const struct operator_s* operator_loop_parallel(unsigned int D, const long dims[D], const struct operator_s* op, unsigned int parallel, bool gpu) { unsigned int N = operator_nr_args(op); long strs[N][D]; for (unsigned int i = 0; i < N; i++) { long tdims[D]; merge_dims(D, tdims, dims, operator_arg_domain(op, i)->dims); md_calc_strides(D, strs[i], tdims, operator_arg_domain(op, i)->size); } return operator_loop_parallel2(N, D, dims, strs, op, parallel, gpu); } const struct operator_s* operator_loop(unsigned int D, const long dims[D], const struct operator_s* op) { return operator_loop_parallel(D, dims, op, 0u, false); } struct copy_data_s { INTERFACE(operator_data_t); const struct operator_s* op; unsigned int N; const long** strs; }; static DEF_TYPEID(copy_data_s); static void copy_fun(const operator_data_t* _data, unsigned int N, void* args[N]) { const auto data = CAST_DOWN(copy_data_s, _data); const struct operator_s* op = data->op; void* ptr[N]; assert(N == operator_nr_args(op)); for (unsigned int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); ptr[i] = md_alloc(io->N, io->dims, io->size); if (!MD_IS_SET(op->io_flags, i)) md_copy2(io->N, io->dims, io->strs, ptr[i], data->strs[i], args[i], io->size); } operator_generic_apply_unchecked(op, N, ptr); for (unsigned int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); if (MD_IS_SET(op->io_flags, i)) md_copy2(io->N, io->dims, data->strs[i], args[i], io->strs, ptr[i], io->size); md_free(ptr[i]); } } static void copy_del(const operator_data_t* _data) { const auto data = CAST_DOWN(copy_data_s, _data); operator_free(data->op); for (unsigned int i = 0; i < data->N; i++) xfree(data->strs[i]); xfree(data->strs); xfree(data); } const struct operator_s* operator_copy_wrapper(unsigned int N, const long* strs[N], const struct operator_s* op) { assert(N == operator_nr_args(op)); // op = operator_ref(op); PTR_ALLOC(struct copy_data_s, data); SET_TYPEID(copy_data_s, data); data->op = op; unsigned int D[N]; const long* dims[N]; const long* (*strs2)[N] = TYPE_ALLOC(const long*[N]); for (unsigned int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); D[i] = io->N; dims[i] = io->dims; long (*strsx)[io->N] = TYPE_ALLOC(long[io->N]); md_copy_strides(io->N, *strsx, strs[i]); (*strs2)[i] = *strsx; long tstrs[io->N]; md_calc_strides(io->N, tstrs, io->dims, CFL_SIZE); for (unsigned int i = 0; i < io->N; i++) assert(io->strs[i] == tstrs[i]); } data->N = N; data->strs = *strs2; return operator_generic_create2(N, op->io_flags, D, dims, *strs2, CAST_UP(PTR_PASS(data)), copy_fun, copy_del); } struct gpu_data_s { INTERFACE(operator_data_t); long move_flags; const struct operator_s* op; }; static DEF_TYPEID(gpu_data_s); #if defined(USE_CUDA) && defined(_OPENMP) #include #define MAX_CUDA_DEVICES 16 omp_lock_t gpulock[MAX_CUDA_DEVICES]; #endif static void gpuwrp_fun(const operator_data_t* _data, unsigned int N, void* args[N]) { #if defined(USE_CUDA) && defined(_OPENMP) const auto data = CAST_DOWN(gpu_data_s, _data); const auto op = data->op; void* gpu_ptr[N]; assert(N == operator_nr_args(op)); debug_printf(DP_DEBUG1, "GPU start.\n"); int nr_cuda_devices = MIN(cuda_devices(), MAX_CUDA_DEVICES); int gpun = omp_get_thread_num() % nr_cuda_devices; cuda_init(gpun); for (unsigned int i = 0; i < N; i++) { if (!MD_IS_SET(data->move_flags, i)) { gpu_ptr[i] = args[i]; continue; } const struct iovec_s* io = operator_arg_domain(op, i); if (MD_IS_SET(op->io_flags, i)) gpu_ptr[i] = md_alloc_gpu(io->N, io->dims, io->size); else gpu_ptr[i] = md_gpu_move(io->N, io->dims, args[i], io->size); } omp_set_lock(&gpulock[gpun]); operator_generic_apply_unchecked(op, N, gpu_ptr); omp_unset_lock(&gpulock[gpun]); for (unsigned int i = 0; i < N; i++) { if (!MD_IS_SET(data->move_flags, i)) continue; const struct iovec_s* io = operator_arg_domain(op, i); if (MD_IS_SET(op->io_flags, i)) md_copy(io->N, io->dims, args[i], gpu_ptr[i], io->size); md_free(gpu_ptr[i]); } debug_printf(DP_DEBUG1, "GPU end.\n"); #else UNUSED(_data); UNUSED(N); UNUSED(args); assert(0); #endif } static void gpuwrp_del(const operator_data_t* _data) { const auto data = CAST_DOWN(gpu_data_s, _data); operator_free(data->op); xfree(data); } const struct operator_s* operator_gpu_wrapper2(const struct operator_s* op, long move_flags) { unsigned int N = operator_nr_args(op); unsigned int D[N]; const long* dims[N]; const long* strs[N]; for (unsigned int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); D[i] = io->N; dims[i] = io->dims; strs[i] = io->strs; } // op = operator_ref(op); PTR_ALLOC(struct gpu_data_s, data); SET_TYPEID(gpu_data_s, data); data->move_flags = move_flags; data->op = operator_ref(op); return operator_generic_create2(N, op->io_flags, D, dims, strs, CAST_UP(PTR_PASS(data)), gpuwrp_fun, gpuwrp_del); } const struct operator_s* operator_gpu_wrapper(const struct operator_s* op) { return operator_gpu_wrapper2(op, ~0L); } struct operator_combi_s { INTERFACE(operator_data_t); int N; const struct operator_s** x; }; static DEF_TYPEID(operator_combi_s); static void combi_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { auto data = CAST_DOWN(operator_combi_s, _data); debug_printf(DP_DEBUG4, "combi apply: ops: %d args: %d\n", data->N, N); int off = N; for (int i = (int)data->N - 1; 0 <= i; i--) { int A = operator_nr_args(data->x[i]); off -= A; for (int a = 0; a < A; a++) debug_printf(DP_DEBUG4, "combi apply: op[%d].arg[%d] == %p\n", i, a, args[off + a]); assert(0 <= off); assert(off < (int)N); operator_generic_apply_unchecked(data->x[i], A, args + off); } assert(0 == off); } static void combi_free(const operator_data_t* _data) { auto data = CAST_DOWN(operator_combi_s, _data); for (int i = 0; i < data->N; i++) operator_free(data->x[i]); xfree(data->x); xfree(data); } /** * Create a new operator that combines several others */ const struct operator_s* operator_combi_create(int N, const struct operator_s* x[N]) { PTR_ALLOC(struct operator_combi_s, c); SET_TYPEID(operator_combi_s, c); PTR_ALLOC(const struct operator_s*[N], xp); for (int i = 0; i < N; i++) (*xp)[i] = operator_ref(x[i]); c->x = *PTR_PASS(xp); c->N = N; int A = 0; for (int i = 0; i < N; i++) A += operator_nr_args(x[i]); unsigned int io_flags = 0;; unsigned int D[A]; const long* dims[A]; const long* strs[A]; int a = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < (int)operator_nr_args(x[i]); j++) { auto iov = operator_arg_domain(x[i], j); D[a] = iov->N; dims[a] = iov->dims; strs[a] = iov->strs; io_flags |= ((x[i]->io_flags >> j) & 1) << a; a++; } } return operator_generic_create2(A, io_flags, D, dims, strs, CAST_UP(PTR_PASS(c)), combi_apply, combi_free); } struct operator_dup_s { INTERFACE(operator_data_t); int a; int b; const struct operator_s* x; }; static DEF_TYPEID(operator_dup_s); static void dup_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { auto data = CAST_DOWN(operator_dup_s, _data); debug_printf(DP_DEBUG4, "dup apply: duplicating %d-%d from %d (io flags: %d)\n", data->a, data->b, N + 1, data->x->io_flags); void* args2[N + 1]; for (int i = 0, j = 0; j < (int)(N + 1); j++) { if (data->b == j) continue; args2[j] = args[i++]; } assert(N > 0); auto iov = operator_arg_domain(data->x, data->a); auto iovb = operator_arg_domain(data->x, data->b); assert(iovec_check(iovb, iov->N, iov->dims, iov->strs)); assert(N + 1 == operator_nr_args(data->x)); args2[data->b] = args2[data->a]; operator_generic_apply_unchecked(data->x, N + 1, args2); } static void dup_del(const operator_data_t* _data) { auto data = CAST_DOWN(operator_dup_s, _data); operator_free(data->x); xfree(data); } const struct operator_s* operator_dup_create(const struct operator_s* op, unsigned int a, unsigned int b) { unsigned int N = operator_nr_args(op); assert(a < N); assert(b < N); assert(a != b); unsigned int io_flags = 0u; unsigned int D[N - 1]; const long* dims[N - 1]; const long* strs[N - 1]; debug_printf(DP_DEBUG3, "Duplicating args %d-%d of %d.\n", a, b, N); for (unsigned int s = 0, t = 0; s < N; s++) { if (s == b) continue; auto io = operator_arg_domain(op, s); D[t] = io->N; dims[t] = io->dims; strs[t] = io->strs; io_flags |= ((op->io_flags >> s) & 1) << t; t++; } auto ioa = operator_arg_domain(op, a); auto iob = operator_arg_domain(op, b); assert(ioa->N == md_calc_blockdim(ioa->N, ioa->dims, ioa->strs, ioa->size)); assert(iob->N == md_calc_blockdim(iob->N, iob->dims, iob->strs, iob->size)); PTR_ALLOC(struct operator_dup_s, data); SET_TYPEID(operator_dup_s, data); data->a = a; data->b = b; data->x = operator_ref(op); return operator_generic_create2(N - 1, io_flags, D, dims, strs, CAST_UP(PTR_PASS(data)), dup_apply, dup_del); } // FIXME: we should reimplement link in terms of dup and bind (caveat: gpu) struct operator_link_s { INTERFACE(operator_data_t); int a; int b; const struct operator_s* x; }; static DEF_TYPEID(operator_link_s); static void link_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { auto data = CAST_DOWN(operator_link_s, _data); debug_printf(DP_DEBUG4, "link apply: linking %d-%d of %d (io flags: %d)\n", data->a, data->b, N + 2, data->x->io_flags); void* args2[N + 2]; for (int i = 0, j = 0; j < (int)(N + 2); j++) { if ((data->a == j) || (data->b == j)) continue; debug_printf(DP_DEBUG4, "link apply: in arg[%d] = %p\n", i, args[i]); debug_printf(DP_DEBUG4, "link apply: mapping %d -> %d\n", i, j); args2[j] = args[i++]; } assert(N > 0); auto iov = operator_arg_domain(data->x, data->a); auto iovb = operator_arg_domain(data->x, data->b); assert(iovec_check(iovb, iov->N, iov->dims, iov->strs)); void* tmp = md_alloc_sameplace(iov->N, iov->dims, iov->size, args[0]); assert(N + 2 == operator_nr_args(data->x)); args2[data->a] = tmp; args2[data->b] = tmp; debug_printf(DP_DEBUG4, "link apply: %d-%d == %p\n", data->a, data->b, tmp); for (int i = 0; i < (int)(N + 2); i++) debug_printf(DP_DEBUG4, "link apply: out arg[%d] = %p\n", i, args2[i]); operator_generic_apply_unchecked(data->x, N + 2, args2); md_free(tmp); } static void link_del(const operator_data_t* _data) { auto data = CAST_DOWN(operator_link_s, _data); operator_free(data->x); xfree(data); } const struct operator_s* operator_link_create(const struct operator_s* op, unsigned int o, unsigned int i) { unsigned int N = operator_nr_args(op); assert(i < N); assert(o < N); assert(i != o); assert( (op->io_flags & MD_BIT(o))); assert(~(op->io_flags & MD_BIT(i))); unsigned int io_flags = 0u; unsigned int D[N - 2]; const long* dims[N - 2]; const long* strs[N - 2]; debug_printf(DP_DEBUG3, "Linking args %d-%d of %d.\n", i, o, N); for (unsigned int s = 0, t = 0; s < N; s++) { if ((s == i) || (s == o)) continue; auto io = operator_arg_domain(op, s); D[t] = io->N; dims[t] = io->dims; strs[t] = io->strs; io_flags |= ((op->io_flags >> s) & 1) << t; t++; } auto ioi = operator_arg_domain(op, i); auto ioo = operator_arg_domain(op, o); assert(ioi->N == md_calc_blockdim(ioi->N, ioi->dims, ioi->strs, ioi->size)); assert(ioo->N == md_calc_blockdim(ioo->N, ioo->dims, ioo->strs, ioo->size)); PTR_ALLOC(struct operator_link_s, data); SET_TYPEID(operator_link_s, data); data->a = i; data->b = o; data->x = operator_ref(op); return operator_generic_create2(N - 2, io_flags, D, dims, strs, CAST_UP(PTR_PASS(data)), link_apply, link_del); } struct permute_data_s { INTERFACE(operator_data_t); const int* perm; const struct operator_s* op; }; static DEF_TYPEID(permute_data_s); static void permute_fun(const operator_data_t* _data, unsigned int N, void* args[N]) { auto data = CAST_DOWN(permute_data_s, _data); assert(N == operator_nr_args(data->op)); void* ptr[N]; for (int i = 0; i < (int)N; i++) ptr[data->perm[i]] = args[i]; for (int i = 0; i < (int)N; i++) debug_printf(DP_DEBUG4, "permute apply: in arg[%d] = %p\n", i, args[i]); for (int i = 0; i < (int)N; i++) debug_printf(DP_DEBUG4, "permute apply: out arg[%d] = %p\n", i, ptr[i]); operator_generic_apply_unchecked(data->op, N, ptr); } static void permute_del(const operator_data_t* _data) { auto data = CAST_DOWN(permute_data_s, _data); operator_free(data->op); xfree(data->perm); xfree(data); } const struct operator_s* operator_permute(const struct operator_s* op, int N, const int perm[N]) { assert(N == (int)operator_nr_args(op)); unsigned long flags = 0; unsigned long io_flags = 0; unsigned int D[N]; const long* dims[N]; const long* strs[N]; for (int i = 0; i < N; i++) { assert(perm[i] < N); flags |= MD_BIT(perm[i]); const struct iovec_s* io = operator_arg_domain(op, perm[i]); D[i] = io->N; dims[i] = io->dims; strs[i] = io->strs; if (op->io_flags & MD_BIT(perm[i])) io_flags |= 1 << i; } assert(MD_BIT(N) == flags + 1); // op = operator_ref(op); PTR_ALLOC(struct permute_data_s, data); SET_TYPEID(permute_data_s, data); data->op = operator_ref(op); int* nperm = *TYPE_ALLOC(int[N]); memcpy(nperm, perm, sizeof(int[N])); data->perm = nperm; return operator_generic_create2(N, io_flags, D, dims, strs, CAST_UP(PTR_PASS(data)), permute_fun, permute_del); } struct extract_data_s { INTERFACE(operator_data_t); int a; size_t off; const struct operator_s* op; }; static DEF_TYPEID(extract_data_s); static void extract_fun(const operator_data_t* _data, unsigned int N, void* args[N]) { auto data = CAST_DOWN(extract_data_s, _data); assert(N == operator_nr_args(data->op)); void* ptr[N]; for (int i = 0; i < (int)N; i++) ptr[i] = args[i] + ((data->a == i) ? data->off : 0); operator_generic_apply_unchecked(data->op, N, ptr); } static void extract_del(const operator_data_t* _data) { auto data = CAST_DOWN(extract_data_s, _data); operator_free(data->op); xfree(data); } const struct operator_s* operator_extract_create2(const struct operator_s* op, int a, int Da, const long dimsa[Da], const long strsa[Da], const long pos[Da]) { int N = (int)operator_nr_args(op); assert(a < N); unsigned int D[N]; const long* dims[N]; const long* strs[N]; for (int i = 0; i < N; i++) { const struct iovec_s* io = operator_arg_domain(op, i); D[i] = io->N; dims[i] = io->dims; strs[i] = io->strs; } assert(Da == (int)D[a]); for (int i = 0; i < Da; i++) { assert((0 <= pos[i]) && (pos[i] < dimsa[i])); assert(dims[a][i] + pos[i] <= dimsa[i]); assert((0 == strs[a][i]) || (strs[a][i] == strsa[i])); } dims[a] = dimsa; strs[a] = strsa; PTR_ALLOC(struct extract_data_s, data); SET_TYPEID(extract_data_s, data); data->op = operator_ref(op); data->a = a; data->off = md_calc_offset(Da, strsa, pos); return operator_generic_create2(N, op->io_flags, D, dims, strs, CAST_UP(PTR_PASS(data)), extract_fun, extract_del); } const struct operator_s* operator_extract_create(const struct operator_s* op, int a, int Da, const long dimsa[Da], const long pos[Da]) { return operator_extract_create2(op, a, Da, dimsa, MD_STRIDES(Da, dimsa, operator_arg_domain(op, a)->size), pos); } static bool stack_compatible(unsigned int D, const struct iovec_s* a, const struct iovec_s* b) { if (a->N != b->N) return false; unsigned int N = a->N; for (unsigned int i = 0; i < N; i++) if ((D != i) && ((a->dims[i] != b->dims[i] || (a->strs[i] != b->strs[i])))) return false; if ((1 != a->dims[D]) && (1 != b->dims[D])) if (a->strs[D] != b->strs[D]) return false; long dims[N]; md_select_dims(N, ~MD_BIT(D), dims, a->dims); long S = md_calc_size(N, dims) * a->size; if ((1 != a->dims[D]) && (S != a->strs[D])) return false; if ((1 != b->dims[D]) && (S != b->strs[D])) return false; return true; } static void stack_dims(unsigned int N, long dims[N], long strs[N], unsigned int D, const struct iovec_s* a, const struct iovec_s* b) { md_copy_dims(N, dims, a->dims); md_copy_strides(N, strs, a->strs); long dimsa[N]; md_select_dims(N, ~MD_BIT(D), dimsa, a->dims); strs[D] = md_calc_size(N, dimsa) * a->size; dims[D] = a->dims[D] + b->dims[D]; } const struct operator_s* operator_stack2(int M, const int arg_list[M], const int dim_list[M], const struct operator_s* a, const struct operator_s* b) { a = operator_ref(a); b = operator_ref(b); for (int m = 0; m < M; m++) { int arg = arg_list[m]; int dim = dim_list[m]; auto ia = operator_arg_domain(a, arg); auto ib = operator_arg_domain(b, arg); assert(stack_compatible(dim, ia, ib)); int D = ia->N; long dims[D]; long strs[D]; stack_dims(D, dims, strs, dim, ia, ib); long pos[D]; for (int i = 0; i < D; i++) pos[i] = 0; auto aa = operator_extract_create2(a, arg, D, dims, strs, (pos[dim] = 0, pos)); auto bb = operator_extract_create2(b, arg, D, dims, strs, (pos[dim] = 1, pos)); operator_free(a); operator_free(b); a = aa; b = bb; } auto c = operator_combi_create(2, MAKE_ARRAY(a, b)); operator_free(a); operator_free(b); int N = operator_nr_args(a); for (int i = N - 1; i >= 0; i--) { auto d = operator_dup_create(c, i, N + i); operator_free(c); c = d; } return c; } /** * Create a new operator that stacks a and b along dimension D */ const struct operator_s* operator_stack(unsigned int D, unsigned int E, const struct operator_s* a, const struct operator_s* b) { return operator_stack2(2, (int[2]){ 0, 1 }, (int[2]){ D, E }, a, b); } bool operator_zero_or_null_p(const struct operator_s* op) { auto opd = operator_get_data(op); if ( (NULL != CAST_MAYBE(zero_s, opd)) || (NULL != CAST_MAYBE(null_s, opd))) return true; auto p = CAST_MAYBE(permute_data_s, opd); if (NULL != p) return operator_zero_or_null_p(p->op); // FIXME: unwrap other types... auto c = CAST_MAYBE(operator_combi_s, opd); if (NULL != c) { for (int i = 0; i < c->N; i++) if (!operator_zero_or_null_p(c->x[i])) return false; return true; } return false; } bart-0.5.00/src/num/ops.h000066400000000000000000000147731353046746100151110ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __OPS_H #define __OPS_H #include "misc/cppwrap.h" #include "misc/types.h" typedef struct operator_data_s { TYPEID* TYPEID; } operator_data_t; typedef void (*operator_fun_t)(const operator_data_t* _data, unsigned int N, void* args[__VLA(N)]); typedef void (*operator_del_t)(const operator_data_t* _data); struct operator_s; // create functions extern const struct operator_s* operator_create(unsigned int ON, const long out_dims[__VLA(ON)], unsigned int IN, const long in_dims[__VLA(IN)], operator_data_t* data, operator_fun_t apply, operator_del_t del); extern const struct operator_s* operator_create2(unsigned int ON, const long out_dims[__VLA(ON)], const long out_strs[__VLA(ON)], unsigned int IN, const long in_dims[__VLA(IN)], const long in_strs[__VLA(IN)], operator_data_t* data, operator_fun_t apply, operator_del_t del); extern const struct operator_s* operator_generic_create(unsigned int N, unsigned int io_flags, const unsigned int D[__VLA(N)], const long* out_dims[__VLA(N)], operator_data_t* data, operator_fun_t apply, operator_del_t del); extern const struct operator_s* operator_generic_create2(unsigned int N, unsigned int io_flags, const unsigned int D[__VLA(N)], const long* out_dims[__VLA(N)], const long* out_strs[__VLA(N)], operator_data_t* data, operator_fun_t apply, operator_del_t del); extern const struct operator_s* operator_identity_create(unsigned int N, const long dims[__VLA(N)]); extern const struct operator_s* operator_identity_create2(unsigned int N, const long dims[__VLA(N)], const long ostr[__VLA(N)], const long istr[__VLA(N)]); extern const struct operator_s* operator_zero_create(unsigned int N, const long dims[N]); extern const struct operator_s* operator_zero_create2(unsigned int N, const long dims[N], const long ostrs[N]); extern const struct operator_s* operator_null_create(unsigned int N, const long dims[N]); extern const struct operator_s* operator_null_create2(unsigned int N, const long dims[N], const long ostrs[N]); extern const struct operator_s* operator_chain(const struct operator_s* a, const struct operator_s* b); extern const struct operator_s* operator_chainN(unsigned int N, const struct operator_s* ops[__VLA(N)]); //extern const struct operator_s* operator_mul(const struct operator_s* a, const struct operator_s* b); //extern const struct operator_s* operator_sum(const struct operator_s* a, const struct operator_s* b); extern const struct operator_s* operator_stack(unsigned int D, unsigned int E, const struct operator_s* a, const struct operator_s* b); extern const struct operator_s* operator_stack2(int M, const int args[M], const int dims[M], const struct operator_s* a, const struct operator_s* b); extern const struct operator_s* operator_bind2(const struct operator_s* op, unsigned int arg, unsigned int N, const long dims[__VLA(N)], const long strs[__VLA(N)], void* ptr); extern const struct operator_s* operator_attach(const struct operator_s* op, void* ptr, void (*del)(const void* ptr)); // del functions extern void operator_free(const struct operator_s* x); extern const struct operator_s* operator_ref(const struct operator_s* x); extern const struct operator_s* operator_unref(const struct operator_s* x); #define OP_PASS(x) (operator_unref(x)) // apply functions extern void operator_generic_apply_unchecked(const struct operator_s* op, unsigned int N, void* args[__VLA(N)]); extern void operator_apply(const struct operator_s* op, unsigned int ON, const long odims[__VLA(ON)], _Complex float* dst, const long IN, const long idims[__VLA(IN)], const _Complex float* src); extern void operator_apply2(const struct operator_s* op, unsigned int ON, const long odims[__VLA(ON)], const long ostrs[__VLA(ON)], _Complex float* dst, const long IN, const long idims[__VLA(IN)], const long istrs[__VLA(IN)], const _Complex float* src); extern void operator_apply_unchecked(const struct operator_s* op, _Complex float* dst, const _Complex float* src); // get functions struct iovec_s; extern unsigned int operator_nr_args(const struct operator_s* op); extern unsigned int operator_nr_in_args(const struct operator_s* op); extern unsigned int operator_nr_out_args(const struct operator_s* op); extern unsigned int operator_ioflags(const struct operator_s* op); extern const struct iovec_s* operator_arg_domain(const struct operator_s* op, unsigned int n); extern const struct iovec_s* operator_domain(const struct operator_s* op); extern const struct iovec_s* operator_codomain(const struct operator_s* op); extern operator_data_t* operator_get_data(const struct operator_s* op); extern const struct operator_s* operator_copy_wrapper(unsigned int N, const long* strs[N], const struct operator_s* op); extern const struct operator_s* operator_gpu_wrapper2(const struct operator_s* op, long move_flags); extern const struct operator_s* operator_gpu_wrapper(const struct operator_s* op); extern const struct operator_s* operator_loop2(unsigned int N, const unsigned int D, const long dims[D], const long (*strs)[D], const struct operator_s* op); const struct operator_s* operator_loop_parallel2(unsigned int N, const unsigned int D, const long dims[D], const long (*strs)[D], const struct operator_s* op, unsigned int flags, _Bool gpu); extern const struct operator_s* operator_loop(unsigned int D, const long dims[D], const struct operator_s* op); extern const struct operator_s* operator_loop_parallel(unsigned int D, const long dims[D], const struct operator_s* op, unsigned int parallel, _Bool gpu); extern const struct operator_s* operator_combi_create(int N, const struct operator_s* x[N]); extern const struct operator_s* operator_link_create(const struct operator_s* op, unsigned int o, unsigned int i); extern const struct operator_s* operator_dup_create(const struct operator_s* op, unsigned int a, unsigned int b); extern const struct operator_s* operator_extract_create(const struct operator_s* op, int a, int N, const long dims[N], const long pos[N]); extern const struct operator_s* operator_extract_create2(const struct operator_s* op, int a, int Da, const long dimsa[Da], const long strsa[Da], const long pos[Da]); extern const struct operator_s* operator_permute(const struct operator_s* op, int N, const int perm[N]); extern _Bool operator_zero_or_null_p(const struct operator_s* op); #include "misc/cppwrap.h" #endif bart-0.5.00/src/num/ops_p.c000066400000000000000000000173731353046746100154220ustar00rootroot00000000000000 #include #include #include #include "num/ops.h" #include "num/iovec.h" #include "num/multind.h" #include "num/flpmath.h" #include "misc/shrdptr.h" #include "misc/misc.h" #include "misc/debug.h" #include "ops_p.h" // copy from num/ops.c struct operator_s { unsigned int N; unsigned int io_flags; const struct iovec_s** domain; operator_data_t* data; void (*apply)(const operator_data_t* data, unsigned int N, void* args[N]); void (*del)(const operator_data_t* data); struct shared_obj_s sptr; }; struct operator_p_s { // struct operator_s op; }; const struct operator_p_s* operator_p_ref(const struct operator_p_s* x) { if (NULL != x) operator_ref((const struct operator_s*)x); return x; } /** * Return the dimensions and strides of the domain of an operator_p * * @param op operator_p */ const struct iovec_s* operator_p_domain(const struct operator_p_s* _op) { auto op = (const struct operator_s*)_op; assert(3 == op->N); assert(2u == op->io_flags); return op->domain[2]; } /** * Return the dimensions and strides of the codomain of an operator_p * * @param op operator_p */ const struct iovec_s* operator_p_codomain(const struct operator_p_s* _op) { auto op = (const struct operator_s*)_op; assert(3 == op->N); assert(2u == op->io_flags); return op->domain[1]; } void operator_p_free(const struct operator_p_s* x) { if (NULL != x) operator_free((const struct operator_s*)x); } struct op_p_data_s { INTERFACE(operator_data_t); operator_data_t* data; operator_p_fun_t apply; operator_del_t del; }; static DEF_TYPEID(op_p_data_s); static void op_p_apply(const operator_data_t* _data, unsigned int N, void* args[N]) { const auto data = CAST_DOWN(op_p_data_s, _data); assert(3 == N); // FIXME: gpu data->apply(data->data, *((float*)args[0]), args[1], args[2]); } static void op_p_del(const operator_data_t* _data) { const auto data = CAST_DOWN(op_p_data_s, _data); data->del(data->data); xfree(data); } operator_data_t* operator_p_get_data(const struct operator_p_s* _data) { const auto data = CAST_DOWN(op_p_data_s, operator_get_data(operator_p_upcast(_data))); return data->data; } static void operator_del(const struct shared_obj_s* sptr) { const struct operator_s* x = CONTAINER_OF(sptr, const struct operator_s, sptr); if (NULL != x->del) x->del(x->data); for (unsigned int i = 0; i < x->N; i++) iovec_free(x->domain[i]); xfree(x->domain); xfree(x); } /** * Create an operator with one parameter (without strides) */ const struct operator_p_s* operator_p_create2(unsigned int ON, const long out_dims[ON], const long out_strs[ON], unsigned int IN, const long in_dims[IN], const long in_strs[IN], operator_data_t* data, operator_p_fun_t apply, operator_del_t del) { PTR_ALLOC(struct operator_s, o); PTR_ALLOC(struct op_p_data_s, op); SET_TYPEID(op_p_data_s, op); op->data = data; op->apply = apply; op->del = del; PTR_ALLOC(const struct iovec_s*[3], dom); (*dom)[0] = iovec_create2(1, MD_DIMS(1), MD_DIMS(0), FL_SIZE); (*dom)[1] = iovec_create2(ON, out_dims, out_strs, CFL_SIZE); (*dom)[2] = iovec_create2(IN, in_dims, in_strs, CFL_SIZE); o->N = 3; o->io_flags = MD_BIT(1); o->domain = *PTR_PASS(dom); o->data = CAST_UP(PTR_PASS(op)); o->apply = op_p_apply; o->del = op_p_del; shared_obj_init(&o->sptr, operator_del); if (NULL == del) debug_printf(DP_WARN, "Warning: no delete function specified for operator_p_create! Possible memory leak.\n"); return operator_p_downcast(PTR_PASS(o)); } /** * Create an operator with one parameter (without strides) * * @param ON number of output dimensions * @param out_dims dimensions of output * @param IN number of input dimensions * @param in_dims dimensions of input * @param data data for applying the operation * @param apply function that applies the operation * @param del function that frees the data */ const struct operator_p_s* operator_p_create(unsigned int ON, const long out_dims[ON], unsigned int IN, const long in_dims[IN], operator_data_t* data, operator_p_fun_t apply, operator_del_t del) { return operator_p_create2(ON, out_dims, MD_STRIDES(ON, out_dims, CFL_SIZE), IN, in_dims, MD_STRIDES(IN, in_dims, CFL_SIZE), data, apply, del); } const struct operator_s* operator_p_upcast(const struct operator_p_s* op) { return (const struct operator_s*)op; } const struct operator_p_s* operator_p_downcast(const struct operator_s* op) { assert(3 == op->N); assert(2u == op->io_flags); return (const struct operator_p_s*)op; } const struct operator_p_s* operator_p_pre_chain(const struct operator_s* a, const struct operator_p_s* _b) { auto b = operator_p_upcast(_b); assert((2 == a->N) && (3 == b->N)); const struct operator_s* x = operator_combi_create(2, MAKE_ARRAY(b, a)); const struct operator_s* y = operator_link_create(x, 3, 2); // mu bo bi a0 ai operator_free(x); return operator_p_downcast(y); } const struct operator_p_s* operator_p_pst_chain(const struct operator_p_s* _a, const struct operator_s* b) { const struct operator_s* a = (const struct operator_s*)_a; assert((3 == a->N) && (2 == b->N)); const struct operator_s* x = operator_combi_create(2, MAKE_ARRAY(b, a)); const struct operator_s* y = operator_link_create(x, 3, 1); // bo bi, mu a0 ai const struct operator_s* z = operator_permute(y, 3, (int[]){ 1, 0, 2 }); operator_free(x); operator_free(y); return operator_p_downcast(z); } void operator_p_apply2(const struct operator_p_s* _op, float mu, unsigned int ON, const long odims[ON], const long ostrs[ON], complex float* dst, const long IN, const long idims[IN], const long istrs[IN], const complex float* src) { auto op = operator_p_upcast(_op); assert(3 == op->N); assert(iovec_check(op->domain[2], IN, idims, istrs)); assert(iovec_check(op->domain[1], ON, odims, ostrs)); operator_p_apply_unchecked(_op, mu, dst, src); } void operator_p_apply(const struct operator_p_s* op, float mu, unsigned int ON, const long odims[ON], complex float* dst, const long IN, const long idims[IN], const complex float* src) { operator_p_apply2(op, mu, ON, odims, MD_STRIDES(ON, odims, CFL_SIZE), dst, IN, idims, MD_STRIDES(IN, idims, CFL_SIZE), src); } void operator_p_apply_unchecked(const struct operator_p_s* _op, float mu, complex float* dst, const complex float* src) { auto op = operator_p_upcast(_op); assert(3 == op->N); op->apply(op->data, 3, (void*[3]){ &mu, (void*)dst, (void*)src }); } const struct operator_s* operator_p_bind(const struct operator_p_s* op, float alpha) { float* nalpha = xmalloc(sizeof(float)); *nalpha = alpha; return operator_attach(operator_bind2(operator_p_upcast(op), 0, 1, (long[]){ 1 }, (long[]){ 0 }, nalpha), nalpha, xfree); } const struct operator_p_s* operator_p_gpu_wrapper(const struct operator_p_s* op) { return operator_p_downcast(operator_gpu_wrapper2(operator_p_upcast(op), MD_BIT(1) | MD_BIT(2))); } const struct operator_p_s* operator_p_stack(int A, int B, const struct operator_p_s* _a, const struct operator_p_s* _b) { auto a = operator_p_upcast(_a); auto b = operator_p_upcast(_b); auto c = operator_stack2(2, (int[]){ 1, 2 }, (int[]){ A, B }, a, b); return operator_p_downcast(c); } struct scale_s { INTERFACE(operator_data_t); long size; }; DEF_TYPEID(scale_s); static void op_p_scale_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { auto data = CAST_DOWN(scale_s, _data); md_zsmul(1, MD_DIMS(data->size), dst, src, mu); } static void op_p_scale_del(const operator_data_t* _data) { xfree(CAST_DOWN(scale_s, _data)); } const struct operator_p_s* operator_p_scale(int N, const long dims[N]) { PTR_ALLOC(struct scale_s, data); SET_TYPEID(scale_s, data); data->size = md_calc_size(N, dims); return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), op_p_scale_apply, op_p_scale_del); } bart-0.5.00/src/num/ops_p.h000066400000000000000000000051011353046746100154110ustar00rootroot00000000000000 struct operator_data_s; typedef struct operator_data_s operator_data_t; typedef void (*operator_p_fun_t)(const operator_data_t* _data, float mu, _Complex float* _dst, const _Complex float* _src); typedef void (*operator_del_t)(const operator_data_t* _data); struct operator_s; struct operator_p_s; extern const struct operator_p_s* operator_p_create(unsigned int ON, const long out_dims[__VLA(ON)], unsigned int IN, const long in_dims[__VLA(IN)], operator_data_t* data, operator_p_fun_t apply, operator_del_t del); extern const struct operator_p_s* operator_p_create2(unsigned int ON, const long out_dims[__VLA(ON)], const long out_strs[__VLA(ON)], unsigned int IN, const long in_dims[__VLA(IN)], const long in_strs[__VLA(IN)], operator_data_t* data, operator_p_fun_t apply, operator_del_t del); extern void operator_p_free(const struct operator_p_s* x); extern const struct operator_p_s* operator_p_ref(const struct operator_p_s* x); extern const struct operator_p_s* operator_p_pre_chain(const struct operator_s* a, const struct operator_p_s* b); extern const struct operator_p_s* operator_p_pst_chain(const struct operator_p_s* a, const struct operator_s* b); extern const struct operator_s* operator_p_bind(const struct operator_p_s* op, float alpha); extern const struct operator_p_s* operator_p_stack(int A, int B, const struct operator_p_s* a, const struct operator_p_s* b); extern const struct operator_p_s* operator_p_scale(int N, const long dims[N]); extern void operator_p_apply(const struct operator_p_s* op, float mu, unsigned int ON, const long odims[__VLA(ON)], _Complex float* dst, const long IN, const long idims[__VLA(IN)], const _Complex float* src); extern void operator_p_apply2(const struct operator_p_s* op, float mu, unsigned int ON, const long odims[__VLA(ON)], const long ostrs[__VLA(ON)], _Complex float* dst, const long IN, const long idims[__VLA(IN)], const long istrs[__VLA(IN)], const _Complex float* src); extern void operator_p_apply_unchecked(const struct operator_p_s* op, float mu, _Complex float* dst, const _Complex float* src); // get functions struct iovec_s; extern const struct iovec_s* operator_p_domain(const struct operator_p_s* op); extern const struct iovec_s* operator_p_codomain(const struct operator_p_s* op); extern operator_data_t* operator_p_get_data(const struct operator_p_s* x); extern const struct operator_s* operator_p_upcast(const struct operator_p_s* op); extern const struct operator_p_s* operator_p_downcast(const struct operator_s* op); extern const struct operator_p_s* operator_p_gpu_wrapper(const struct operator_p_s* op); bart-0.5.00/src/num/optimize.c000066400000000000000000000310311353046746100161250ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2017 Martin Uecker * * * Optimization framework for operations on multi-dimensional arrays. * */ #include #include #include #include #include #include #include "misc/misc.h" #include "misc/debug.h" #include "misc/nested.h" #include "num/multind.h" #include "num/vecops.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "num/simplex.h" #include "optimize.h" /* * Helper functions: * * 1. detect aliasing * 2. detect if dimensions can be merged * 3. compute memory footprint * */ #if 0 static bool regular(long dim, long str) { return (dim > 0) && (str > 0); } static bool singular(long dim, long str) { assert(dim > 0); return (1 == dim) || (0 == str); } static bool enclosed(const long dims[2], const long strs[2]) { assert(regular(dims[0], strs[0])); assert(regular(dims[1], strs[1])); return (strs[1] >= dims[0] * strs[0]); } // assumes no overlap static long memory_footprint(int N, const long dims[N], const long strs[N]) { unsigned int flags = 0; for (int i = 0; i < N; i++) flags |= (0 == strs[i]); long dims2[N]; md_select_dims(N, ~flags, dims2, dims); return md_calc_size(N, dims2); } #endif /* * Generic optimizations strategy: * * 1. ordering of dimensions by stride * 2. merging of dimensions * 3. splitting and ordering (cache-oblivious algorithms) * 4. parallelization * */ /* strategies: - cache-oblivous algorithms (e.g. transpose) - use of accelerators - parallelization - vectorization - reordering of memory access - temporaries - loop merging - splitting */ /* * Each parameter is either input or output. The pointers must valid * and all accesses using any position inside the range given by * dimensions and using corresponding strides must be inside of the * adressed memory region. Pointers pointing inside the same region * can be passed multipe times. */ void merge_dims(unsigned int D, unsigned int N, long dims[N], long (*ostrs[D])[N]) { for (int i = N - 2; i >= 0; i--) { bool domerge = true; for (unsigned int j = 0; j < D; j++) // mergeable domerge = domerge && ((*ostrs[j])[i + 1] == dims[i] * (*ostrs[j])[i]); if (domerge) { for (unsigned int j = 0; j < D; j++) (*ostrs[j])[i + 1] = 0; dims[i + 0] *= dims[i + 1]; dims[i + 1] = 1; } } } unsigned int remove_empty_dims(unsigned int D, unsigned int N, long dims[N], long (*ostrs[D])[N]) { unsigned int o = 0; for (unsigned int i = 0; i < N; i++) { if (1 != dims[i]) { dims[o] = dims[i]; for (unsigned int j = 0; j < D; j++) (*ostrs[j])[o] = (*ostrs[j])[i]; o++; } } return o; } static int cmp_strides(const void* _data, int a, int b) { const long* strs = _data; long d = strs[a] - strs[b]; if (d > 0) return 1; if (d < 0) return -1; return 0; } static void compute_permutation(unsigned int N, int ord[N], const long strs[N]) { for (unsigned int i = 0; i < N; i++) ord[i] = i; quicksort(N, ord, (const void*)strs, cmp_strides); } static void reorder_long(int N, int ord[N], long x[N]) { long tmp[N]; memcpy(tmp, x, N * sizeof(long)); for (int i = 0; i < N; i++) x[i] = tmp[ord[i]]; } /* * Jim Demmel's generic blocking theorem */ static void demmel_factors(unsigned int D, unsigned int N, float blocking[N], long (*strs[D])[N]) { float delta[D][N]; for (unsigned int d = 0; d < D; d++) for (unsigned int n = 0; n < N; n++) delta[d][n] = (0 != (*strs[d])[n]) ? 1. : 0.; // now maximize 1^T x subject to Delta x <= 1 // M^{x_n} yields blocking factors where M is cache size (maybe needs to be devided by D?) float ones[MAX(N, D)]; for (unsigned int n = 0; n < MAX(N, D); n++) ones[n] = 1.; simplex(D, N, blocking, ones, ones, (const float (*)[N])delta); } static long find_factor(long x, float blocking) { //long m = (long)(1. + sqrt((double)x)); long m = (long)(1. + pow((double)x, blocking)); for (long i = m; i > 1; i--) if (0 == x % i) return (x / i); return 1; } static bool split_dims(unsigned int D, unsigned int N, long dims[N + 1], long (*ostrs[D])[N + 1], float blocking[N]) { if (0 == N) return false; long f; if ((dims[N - 1] > 1024) && (1 < (f = find_factor(dims[N - 1], blocking[N - 1])))) { #if 1 dims[N - 1] = dims[N - 1] / f; dims[N] = f; for (unsigned int j = 0; j < D; j++) (*ostrs[j])[N] = (*ostrs[j])[N - 1] * dims[N - 1]; blocking[N - 1] = blocking[N - 1]; blocking[N] = blocking[N - 1]; #else dims[N] = 1; for (unsigned int j = 0; j < D; j++) (*ostrs[j])[N] = 0; #endif return true; } // could not split, make room and try lower dimensions dims[N] = dims[N - 1]; blocking[N] = blocking[N - 1]; for (unsigned int j = 0; j < D; j++) (*ostrs[j])[N] = (*ostrs[j])[N - 1]; if (split_dims(D, N - 1, dims, ostrs, blocking)) return true; dims[N - 1] = dims[N]; for (unsigned int j = 0; j < D; j++) (*ostrs[j])[N - 1] = (*ostrs[j])[N]; blocking[N - 1] = blocking[N]; return false; } unsigned int simplify_dims(unsigned int D, unsigned int N, long dims[N], long (*strs[D])[N]) { merge_dims(D, N, dims, strs); unsigned int ND = remove_empty_dims(D, N, dims, strs); if (0 == ND) { // atleast return a single dimension dims[0] = 1; for (unsigned int j = 0; j < D; j++) (*strs[j])[0] = 0; ND = 1; } return ND; } unsigned int optimize_dims(unsigned int D, unsigned int N, long dims[N], long (*strs[D])[N]) { unsigned int ND = simplify_dims(D, N, dims, strs); debug_print_dims(DP_DEBUG4, ND, dims); float blocking[N]; // actually those are not the blocking factors // as used below but relative to fast memory //demmel_factors(D, ND, blocking, strs); UNUSED(demmel_factors); #if 0 debug_printf(DP_DEBUG4, "DB: "); for (unsigned int i = 0; i < ND; i++) debug_printf(DP_DEBUG4, "%f\t", blocking[i]); debug_printf(DP_DEBUG4, "\n"); #endif #if 1 for (unsigned int i = 0; i < ND; i++) blocking[i] = 0.5; // blocking[i] = 1.; #endif // try to split dimensions according to blocking factors // use space up to N bool split = false; do { if (N == ND) break; split = split_dims(D, ND, dims, strs, blocking); if (split) ND++; } while(split); // printf("Split %c :", split ? 'y' : 'n'); // print_dims(ND, dims); long max_strides[ND]; for (unsigned int i = 0; i < ND; i++) { max_strides[i] = 0; for (unsigned int j = 0; j < D; j++) max_strides[i] = MAX(max_strides[i], (*strs[j])[i]); } int ord[ND]; compute_permutation(ND, ord, max_strides); // for (unsigned int i = 0; i < ND; i++) // printf("%d: %ld %d\n", i, max_strides[i], ord[i]); #if 1 for (unsigned int j = 0; j < D; j++) reorder_long(ND, ord, *strs[j]); reorder_long(ND, ord, dims); #endif #if 0 printf("opt dims\n"); print_dims(ND, dims); if (D > 0) print_dims(ND, *strs[0]); if (D > 1) print_dims(ND, *strs[1]); if (D > 2) print_dims(ND, *strs[2]); #endif return ND; } /** * compute minimal dimension of largest contiguous block(s) * */ unsigned int min_blockdim(unsigned int D, unsigned int N, const long dims[N], long (*strs[D])[N], size_t size[D]) { unsigned int mbd = N; for (unsigned int i = 0; i < D; i++) mbd = MIN(mbd, md_calc_blockdim(N, dims, *strs[i], size[i])); return mbd; } static void compute_enclosures(unsigned int N, bool matrix[N][N], const long dims[N], const long strides[N]) { long ext[N]; for (unsigned int i = 0; i < N; i++) ext[i] = dims[i] * labs(strides[i]); for (unsigned int i = 0; i < N; i++) for (unsigned int j = 0; j < N; j++) matrix[i][j] = (ext[i] <= labs(strides[j])); } /** * compute set of parallelizable dimensions * */ static unsigned long parallelizable(unsigned int D, unsigned int io, unsigned int N, const long dims[N], long (*strs[D])[N], size_t size[D]) { // we assume no input / output overlap // (i.e. inputs which are also outputs have to be marked as output) // a dimension is parallelizable if all output operations // for that dimension are independent // for all output operations: // check - all other dimensions have strides greater or equal // the extend of this dimension or have an extend smaller or // equal the stride of this dimension // no overlap: [222] // [111111111111] // [333333333] // overlap: [222] // [1111111111111111] // [333333333] unsigned long flags = (1 << N) - 1; for (unsigned int d = 0; d < D; d++) { if (MD_IS_SET(io, d)) { bool m[N][N]; compute_enclosures(N, m, dims, *strs[d]); // print_dims(N, dims); // print_dims(N, *strs[d]); for (unsigned int i = 0; i < N; i++) { unsigned int a = 0; for (unsigned int j = 0; j < N; j++) if (m[i][j] || m[j][i]) a++; // printf("%d %d %d\n", d, i, a); if ((a != N - 1) || ((size_t)labs((*strs[d])[i]) < size[d])) flags = MD_CLEAR(flags, i); } } } return flags; } extern long num_chunk_size; long num_chunk_size = 32 * 1024; /** * compute set of dimensions to parallelize * */ unsigned long dims_parallel(unsigned int D, unsigned int io, unsigned int N, const long dims[N], long (*strs[D])[N], size_t size[D]) { unsigned long flags = parallelizable(D, io, N, dims, strs, size); unsigned int i = N; long reps = md_calc_size(N, dims); unsigned long oflags = 0; while (i-- > 0) { if (MD_IS_SET(flags, i)) { reps /= dims[i]; if (reps < num_chunk_size) break; oflags = MD_SET(oflags, i); } } return oflags; } #ifdef USE_CUDA static bool use_gpu(int p, void* ptr[p]) { bool gpu = false; for (int i = 0; i < p; i++) gpu |= cuda_ondevice(ptr[i]); for (int i = 0; i < p; i++) gpu &= cuda_accessible(ptr[i]); #if 0 // FIXME: fails for copy if (!gpu) { for (int i = 0; i < p; i++) assert(!cuda_ondevice(ptr[i])); } #endif return gpu; } #endif extern double md_flp_total_time; double md_flp_total_time = 0.; // automatic parallelization extern bool num_auto_parallelize; bool num_auto_parallelize = true; /** * Optimized n-op. * * @param N number of arguments ' @param io bitmask indicating input/output * @param D number of dimensions * @param dim dimensions * @param nstr strides for arguments and dimensions * @param nptr argument pointers * @param sizes size of data for each argument, e.g. complex float * @param too n-op function * @param data_ptr pointer to additional data used by too */ void optimized_nop(unsigned int N, unsigned int io, unsigned int D, const long dim[D], const long (*nstr[N])[D], void* const nptr[N], size_t sizes[N], md_nary_opt_fun_t too) { assert(N > 0); if (0 == D) { long dim1[1] = { 1 }; long tstrs[N][1]; long (*nstr1[N])[1]; for (unsigned int i = 0; i < N; i++) { tstrs[i][0] = 0; nstr1[i] = &tstrs[i]; } optimized_nop(N, io, 1, dim1, (void*)nstr1, nptr, sizes, too); return; } long tdims[D]; md_copy_dims(D, tdims, dim); long tstrs[N][D]; long (*nstr1[N])[D]; void* nptr1[N]; for (unsigned int i = 0; i < N; i++) { md_copy_strides(D, tstrs[i], *nstr[i]); nstr1[i] = &tstrs[i]; nptr1[i] = nptr[i]; } int ND = optimize_dims(N, D, tdims, nstr1); int skip = min_blockdim(N, ND, tdims, nstr1, sizes); unsigned long flags = 0; debug_printf(DP_DEBUG4, "MD-Fun. Io: %d Input: ", io); debug_print_dims(DP_DEBUG4, D, dim); #ifdef USE_CUDA if (num_auto_parallelize && !use_gpu(N, nptr1)) { #else if (num_auto_parallelize) { #endif flags = dims_parallel(N, io, ND, tdims, nstr1, sizes); while ((0 != flags) && (ffs(flags) <= skip)) skip--; flags = flags >> skip; } const long* nstr2[N]; for (unsigned int i = 0; i < N; i++) nstr2[i] = *nstr1[i] + skip; #ifdef USE_CUDA debug_printf(DP_DEBUG4, "This is a %s call\n.", use_gpu(N, nptr1) ? "gpu" : "cpu"); __block struct nary_opt_data_s data = { md_calc_size(skip, tdims), use_gpu(N, nptr1) ? &gpu_ops : &cpu_ops }; #else __block struct nary_opt_data_s data = { md_calc_size(skip, tdims), &cpu_ops }; #endif debug_printf(DP_DEBUG4, "Vec: %d (%ld) Opt.: ", skip, data.size); debug_print_dims(DP_DEBUG4, ND, tdims); NESTED(void, nary_opt, (void* ptr[])) { NESTED_CALL(too, (&data, ptr)); }; double start = timestamp(); md_parallel_nary(N, ND - skip, tdims + skip, flags, nstr2, nptr1, nary_opt); double end = timestamp(); #pragma omp critical md_flp_total_time += end - start; debug_printf(DP_DEBUG4, "MD time: %f\n", end - start); } bart-0.5.00/src/num/optimize.h000066400000000000000000000025031353046746100161340ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus #error This file does not support C++ #endif #include extern void merge_dims(unsigned int D, unsigned int N, long dims[N], long (*ostrs[D])[N]); extern unsigned int remove_empty_dims(unsigned int D, unsigned int N, long dims[N], long (*ostrs[D])[N]); extern unsigned int simplify_dims(unsigned int D, unsigned int N, long dims[N], long (*strs[D])[N]); extern unsigned int optimize_dims(unsigned int D, unsigned int N, long dims[N], long (*strs[D])[N]); extern unsigned int min_blockdim(unsigned int D, unsigned int N, const long dims[N], long (*strs[D])[N], size_t size[D]); extern unsigned long dims_parallel(unsigned int D, unsigned int io, unsigned int N, const long dims[N], long (*strs[D])[N], size_t size[D]); struct vec_ops; struct nary_opt_data_s { long size; const struct vec_ops* ops; }; typedef void CLOSURE_TYPE(md_nary_opt_fun_t)(struct nary_opt_data_s* data, void* ptr[]); extern void optimized_nop(unsigned int N, unsigned int io, unsigned int D, const long dim[D], const long (*nstr[N])[D], void* const nptr[N], size_t sizes[N], md_nary_opt_fun_t too); bart-0.5.00/src/num/polynom.c000066400000000000000000000071571353046746100157760ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include #include #include "polynom.h" complex double polynom_eval(complex double x, int N, const complex double coeff[N + 1]) { // Horner's method: a_0 + x * (a_1 + x * (a_2 + ...) return coeff[0] + ((0 == N) ? 0. : (x * polynom_eval(x, N - 1, coeff + 1))); } void (polynom_derivative)(int N, complex double out[N], const complex double in[N + 1]) { for (int i = 0; i < N; i++) out[i] = (i + 1) * in[i + 1]; } void polynom_integral(int N, complex double out[N + 2], const complex double in[N + 1]) { out[0] = 0.; for (int i = 0; i <= N; i++) out[i + 1] = in[i] / (i + 1); } complex double polynom_integrate(complex double st, complex double end, int N, const complex double coeff[N + 1]) { complex double int_coeff[N + 2]; polynom_integral(N, int_coeff, coeff); return polynom_eval(end, N + 1, int_coeff) - polynom_eval(st, N + 1, int_coeff); } void polynom_monomial(int N, complex double coeff[N + 1], int O) { for (int i = 0; i <= N; i++) coeff[i] = (O == i) ? 1. : 0.; } void polynom_from_roots(int N, complex double coeff[N + 1], const complex double root[N]) { // Vieta's formulas for (int i = 0; i <= N; i++) coeff[i] = 0.; // assert N < for (unsigned long b = 0; b < (1u << N); b++) { complex double prod = 1.; int count = 0; for (int i = 0; i < N; i++) { if (b & (1 << i)) { prod *= -root[i]; count++; } } coeff[N - count] += prod; } } void polynom_scale(int N, complex double out[N + 1], complex double scale, const complex double in[N + 1]) { complex double prod = 1.; for (int i = 0; i <= N; i++) { out[i] = prod * in[i]; prod *= scale; } } void polynom_shift(int N, complex double out[N + 1], complex double shift, const complex double in[N + 1]) { // Taylor shift (there are faster FFT-based methods) for (int i = 0; i <= N; i++) out[i] = 0.; complex double tmp[N + 1]; for (int i = 0; i <= N; i++) tmp[i] = in[i]; complex double prod = 1.; for (int i = 0; i <= N; i++) { for (int j = 0; j <= (N - i); j++) out[j] += prod * tmp[j]; polynom_derivative(N - i, tmp, tmp); prod *= shift; prod /= (i + 1); } } void quadratic_formula(complex double x[2], complex double coeff[3]) { complex double c = coeff[0]; complex double b = coeff[1]; complex double a = coeff[2]; assert(0. != a); complex double t = csqrt(cpow(b, 2.) - 4. * a * c); x[0] = (-b + t) / (2. * a); x[1] = (-b - t) / (2. * a); // FIXME: precision // Citardauq Formula // x[1] = 2. * c / (-b + s * t); } void cubic_formula(complex double x[3], complex double coeff[4]) { complex double a = coeff[3]; complex double b = coeff[2]; complex double c = coeff[1]; complex double d = coeff[0]; assert(0. != a); // depressed form t^3 + p t + q with t = -b / (3 a) complex double p = (3. * a * c - cpow(b, 2.)) / (3. * cpow(a, 2.)); complex double q = (2. * cpow(b, 3.) - 9. * a * b * c + 27. * cpow(a, 2.) * d) / (27. * cpow(a, 3.)); // Vieta's substitution: quadratic in w^3 with t = w - p / (3 w) complex double qp[3] = { -cpow(p, 3.) / 27., q, 1. }; complex double qw[2]; quadratic_formula(qw, qp); if (0. == qw[0]) qw[0] = qw[1]; complex double w1 = cpow(qw[0], 1. / 3.); complex double ksi = 0.5 * (-1. + sqrt(3.) * 1.i); for (int i = 0; i < 3; i++) { complex double wi = cpow(ksi, i) * w1; complex double ti = (0. == wi) ? 0. : (wi - p / (3. * wi)); x[i] = ti - b / (3. * a); } } bart-0.5.00/src/num/polynom.h000066400000000000000000000017311353046746100157730ustar00rootroot00000000000000 #include extern complex double polynom_eval(complex double x, int N, const complex double coeff[N + 1]); extern void polynom_derivative(int N, complex double out[N], const complex double in[N + 1]); extern void polynom_integral(int N, complex double out[N + 2], const complex double in[N + 1]); extern complex double polynom_integrate(complex double st, complex double end, int N, const complex double coeff[N + 1]); extern void polynom_monomial(int N, complex double coeff[N + 1], int O); extern void polynom_from_roots(int N, complex double coeff[N + 1], const complex double root[N]); extern void polynom_scale(int N, complex double out[N + 1], complex double scale, const complex double in[N + 1]); extern void polynom_shift(int N, complex double out[N + 1], complex double shift, const complex double in[N + 1]); extern void quadratic_formula(complex double x[2], complex double coeff[3]); extern void cubic_formula(complex double x[3], complex double coeff[4]); bart-0.5.00/src/num/qform.c000066400000000000000000000022201353046746100154070ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. */ #include #include #include "num/linalg.h" #include "qform.h" float gradient_form(const float qf[3], float phi) { float x = cosf(phi); float y = sinf(phi); return x * x * qf[0] + 2. * x * y * qf[2] + y * y * qf[1]; } void fit_quadratic_form(float qf[3], unsigned int N, const float phi[N], const float v[N]) { complex float lhs[3] = { 0., 0., 0. }; complex float mat[3][3] = { { 0. } }; for (unsigned int i = 0; i < N; i++) { float x = cosf(phi[i]); float y = sinf(phi[i]); lhs[0] += x * x * v[i]; lhs[1] += y * y * v[i]; lhs[2] += 2. * x * y * v[i]; mat[0][0] += x * x * x * x; mat[0][1] += x * x * y * y; mat[0][2] += x * x * 2. * x * y; mat[1][0] += y * y * x * x; mat[1][1] += y * y * y * y; mat[1][2] += y * y * 2. * x * y; mat[2][0] += 2. * x * y * x * x; mat[2][1] += 2. * x * y * y * y; mat[2][2] += 2. * x * y * 2. * x * y; } complex float inv[3][3]; complex float out[3]; mat_inverse(3, inv, mat); mat_vecmul(3, 3, out, inv, lhs); qf[0] = out[0]; qf[1] = out[1]; qf[2] = out[2]; } bart-0.5.00/src/num/qform.h000066400000000000000000000002371353046746100154220ustar00rootroot00000000000000 extern float gradient_form(const float qf[3], float phi); extern void fit_quadratic_form(float qf[3], unsigned int N, const float phi[N], const float v[N]); bart-0.5.00/src/num/rand.c000066400000000000000000000026671353046746100152260ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker * 2013 Dara Bahri */ #define _GNU_SOURCE #include #include #include #include "num/multind.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "rand.h" unsigned int num_rand_seed = 123; void num_rand_init(unsigned int seed) { num_rand_seed = seed; } double uniform_rand(void) { double ret; #pragma omp critical ret = rand_r(&num_rand_seed) / (double)RAND_MAX; return ret; } /** * Box-Muller */ complex double gaussian_rand(void) { double u1, u2, s; do { u1 = 2. * uniform_rand() - 1.; u2 = 2. * uniform_rand() - 1.; s = u1 * u1 + u2 * u2; } while (s > 1.); double re = sqrt(-2. * log(s) / s) * u1; double im = sqrt(-2. * log(s) / s) * u2; return re + 1.i * im; } void md_gaussian_rand(unsigned int D, const long dims[D], complex float* dst) { #ifdef USE_CUDA if (cuda_ondevice(dst)) { complex float* tmp = md_alloc(D, dims, sizeof(complex float)); md_gaussian_rand(D, dims, tmp); md_copy(D, dims, dst, tmp, sizeof(complex float)); md_free(tmp); return; } #endif //#pragma omp parallel for for (long i = 0; i < md_calc_size(D, dims); i++) dst[i] = (complex float)gaussian_rand(); } bart-0.5.00/src/num/rand.h000066400000000000000000000007261353046746100152250ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/cppwrap.h" extern double uniform_rand(void); extern _Complex double gaussian_rand(void); extern void md_gaussian_rand(unsigned int D, const long dims[__VLA(D)], _Complex float* dst); extern void num_rand_init(unsigned int seed); #include "misc/cppwrap.h" bart-0.5.00/src/num/shuffle.c000066400000000000000000000060511353046746100157250ustar00rootroot00000000000000 #include "num/multind.h" #include "misc/debug.h" #include "misc/misc.h" #include "shuffle.h" #if 0 void md_shuffle2(unsigned int N, const long dims[N], const long factors[N], const long ostrs[N], void* out, const long istrs[N], const void* in, size_t size) { long dims2[2 * N]; long ostrs2[2 * N]; long istrs2[2 * N]; for (unsigned int i = 0; i < N; i++) { assert(0 == dims[i] % factors[i]); long f2 = dims[i] / factors[i]; dims2[0 * N + i] = f2; dims2[1 * N + i] = factors[i]; ostrs2[1 * N + i] = ostrs[i]; ostrs2[0 * N + i] = ostrs[i] * f2; istrs2[0 * N + i] = istrs[i] * factors[i]; istrs2[1 * N + i] = istrs[i]; } md_copy2(2 * N, dims2, ostrs2, out, istrs2, in, size); } void md_shuffle(unsigned int N, const long dims[N], const long factors[N], void* out, const void* in, size_t size) { long strs[N]; md_calc_strides(N, strs, dims, size); md_shuffle2(N, dims, factors, strs, out, strs, in, size); } #endif static void decompose_dims(unsigned int N, long dims2[2 * N], long ostrs2[2 * N], long istrs2[2 * N], const long factors[N], const long odims[N + 1], const long ostrs[N + 1], const long idims[N], const long istrs[N]) { long prod = 1; for (unsigned int i = 0; i < N; i++) { long f2 = idims[i] / factors[i]; assert(0 == idims[i] % factors[i]); assert(odims[i] == idims[i] / factors[i]); dims2[1 * N + i] = factors[i]; dims2[0 * N + i] = f2; istrs2[0 * N + i] = istrs[i] * factors[i]; istrs2[1 * N + i] = istrs[i]; ostrs2[0 * N + i] = ostrs[i]; ostrs2[1 * N + i] = ostrs[N] * prod; prod *= factors[i]; } assert(odims[N] == prod); } void md_decompose2(unsigned int N, const long factors[N], const long odims[N + 1], const long ostrs[N + 1], void* out, const long idims[N], const long istrs[N], const void* in, size_t size) { long dims2[2 * N]; long ostrs2[2 * N]; long istrs2[2 * N]; decompose_dims(N, dims2, ostrs2, istrs2, factors, odims, ostrs, idims, istrs); md_copy2(2 * N, dims2, ostrs2, out, istrs2, in, size); } void md_decompose(unsigned int N, const long factors[N], const long odims[N + 1], void* out, const long idims[N], const void* in, size_t size) { long ostrs[N + 1]; md_calc_strides(N + 1, ostrs, odims, size); long istrs[N]; md_calc_strides(N, istrs, idims, size); md_decompose2(N, factors, odims, ostrs, out, idims, istrs, in, size); } void md_recompose2(unsigned int N, const long factors[N], const long odims[N], const long ostrs[N], void* out, const long idims[N + 1], const long istrs[N + 1], const void* in, size_t size) { long dims2[2 * N]; long ostrs2[2 * N]; long istrs2[2 * N]; decompose_dims(N, dims2, istrs2, ostrs2, factors, idims, istrs, odims, ostrs); md_copy2(2 * N, dims2, ostrs2, out, istrs2, in, size); } void md_recompose(unsigned int N, const long factors[N], const long odims[N], void* out, const long idims[N + 1], const void* in, size_t size) { long ostrs[N]; md_calc_strides(N, ostrs, odims, size); long istrs[N + 1]; md_calc_strides(N + 1, istrs, idims, size); md_recompose2(N, factors, odims, ostrs, out, idims, istrs, in, size); } bart-0.5.00/src/num/shuffle.h000066400000000000000000000023261353046746100157330ustar00rootroot00000000000000 #include #include "misc/cppwrap.h" extern void md_shuffle2(unsigned int N, const long dims[__VLA(N)], const long factors[__VLA(N)], const long ostrs[__VLA(N)], void* out, const long istrs[__VLA(N)], const void* in, size_t size); extern void md_shuffle(unsigned int N, const long dims[__VLA(N)], const long factors[__VLA(N)], void* out, const void* in, size_t size); extern void md_decompose2(unsigned int N, const long factors[__VLA(N)], const long odims[__VLA(N + 1)], const long ostrs[__VLA(N + 1)], void* out, const long idims[__VLA(N)], const long istrs[__VLA(N)], const void* in, size_t size); extern void md_decompose(unsigned int N, const long factors[__VLA(N)], const long odims[__VLA(N + 1)], void* out, const long idims[__VLA(N)], const void* in, size_t size); extern void md_recompose2(unsigned int N, const long factors[__VLA(N)], const long odims[__VLA(N)], const long ostrs[__VLA(N)], void* out, const long idims[__VLA(N + 1)], const long istrs[__VLA(N + 1)], const void* in, size_t size); extern void md_recompose(unsigned int N, const long factors[__VLA(N)], const long odims[__VLA(N)], void* out, const long idims[__VLA(N + 1)], const void* in, size_t size); #include "misc/cppwrap.h" bart-0.5.00/src/num/simplex.c000066400000000000000000000104371353046746100157550ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2014 Martin Uecker */ #include #include #include #include "simplex.h" /* * transform matrix so that (d, n) = 1 and (:, n) = 0 */ static void trafo(unsigned int D, unsigned int N, float A[D][N], unsigned int d, unsigned int n) { float mul = A[d][n]; for (unsigned int k = 0; k < N; k++) A[d][k] /= mul; for (unsigned int l = 0; l < D; l++) { if (l != d) { mul = A[l][n]; for (unsigned int k = 0; k < N; k++) A[l][k] -= mul * A[d][k]; } } } static bool feasible_p(unsigned int D, unsigned int N, const float x[N], /*const*/ float A[D + 1][N + 1]) { bool ok = true; for (unsigned int j = 0; j < D; j++) { float sum = 0.; for (unsigned int i = 0; i < N; i++) sum += A[1 + j][i] * x[i]; ok &= (0 == A[1 + j][N] - sum); } return ok; } static void solution(unsigned int D, unsigned int N, float x[N], /*const*/ float A[D + 1][N + 1]) { // this is needed to deel with duplicate columns bool used[D]; for (unsigned int i = 0; i < D; i++) used[i] = false; for (unsigned int i = 0; i < N; i++) { x[i] = -1.; int pos = -1; for (unsigned int j = 0; j < D; j++) { if (0. == A[1 + j][i]) continue; if ((1. == A[1 + j][i]) && (-1. == x[i]) && !used[j]) { x[i] = A[1 + j][N]; pos = j; used[j] = true; } else { x[i] = -1.; break; } } if (-1. == x[i]) { // non-basic x[i] = 0.; if (-1 != pos) used[pos] = false; } } //assert(feasible_p(D, N, x, A)); } extern void print_tableaux(unsigned int D, unsigned int N, /*const*/ float A[D + 1][N + 1]); void print_tableaux(unsigned int D, unsigned int N, /*const*/ float A[D + 1][N + 1]) { float x[N]; solution(D, N, x, A); float y[D]; for (unsigned int j = 0; j < D; j++) { y[j] = 0.; for (unsigned int i = 0; i < N; i++) y[j] += A[1 + j][i] * x[i]; } printf(" "); for (unsigned int i = 0; i < N; i++) printf("x%d ", i); printf("\nSolution: "); for (unsigned int i = 0; i < N; i++) printf(" %0.2f ", x[i]); printf("(%s)\n", (feasible_p(D, N, x, A)) ? "feasible" : "infeasible"); printf(" Max "); for (unsigned int i = 0; i < N; i++) printf("%+0.2f ", A[0][i]); printf(" %+0.2f s.t.:\n", A[0][N]); for (unsigned int j = 0; j < D; j++) { printf(" "); for (unsigned int i = 0; i < N; i++) printf("%+0.2f ", A[1 + j][i]); printf("= %+0.2f | %+0.2f\n", A[1 + j][N], y[j]); } printf("Objective: %0.2f\n", A[0][N]); } /* * maximize c^T x subject to Ax = b and x >= 0 * * inplace, b is last column of A, c first row */ static void simplex2(unsigned int D, unsigned int N, float A[D + 1][N + 1]) { // 2. Loop over all columns // print_tableaux(D, N, A); while (true) { unsigned int i = 0; for (i = 0; i < N; i++) if (A[0][i] < 0.) break; if (i == N) break; // 3. find pivot element // Bland's rule int pivot_index = -1; float pivot_value = 0.; for (unsigned int j = 1; j < D + 1; j++) { if (0. < A[j][i]) { float nval = A[j][N] / A[j][i]; if ((-1 == pivot_index) || (nval < pivot_value)) { pivot_value = nval; pivot_index = j; } } } if (-1 == pivot_index) break; // printf("PI %dx%d\n", pivot_index, i); trafo(D + 1, N + 1, A, pivot_index, i); // print_tableaux(D, N, A); float x[N]; solution(D, N, x, A); assert(feasible_p(D, N, x, A)); } // print_tableaux(D, N, A); } /* * maximize c^T x subject to Ax <= b and x >= 0 */ void (simplex)(unsigned int D, unsigned int N, float x[N], const float c[N], const float b[D], const float A[D][N]) { // 1. Step: slack variables // max c^T x Ax + z = b x,z >= 0 float A2[D + 1][N + D + 1]; for (unsigned int i = 0; i < N + D + 1; i++) { A2[0][i] = (i < N) ? -c[i] : 0.; for (unsigned int j = 0; j < D; j++) { if (i < N) A2[1 + j][i] = A[j][i]; else if (i == N + D) A2[1 + j][i] = b[j]; else A2[1 + j][i] = (i - N == j) ? 1. : 0.; } } simplex2(D, N + D, A2); // extract results: float x2[D + N]; solution(D, D + N, x2, A2); for (unsigned int i = 0; i < N; i++) x[i] = x2[i]; } bart-0.5.00/src/num/simplex.h000066400000000000000000000001751353046746100157600ustar00rootroot00000000000000 extern void simplex(unsigned int D, unsigned int N, float x[N], const float c[N], const float b[D], const float A[D][N]); bart-0.5.00/src/num/specfun.c000066400000000000000000000023361353046746100157360ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * Martin Uecker */ #include #include "misc/misc.h" #include "num/chebfun.h" #include "specfun.h" /* FIXME: improve precision * (but should be good enough for our purposes...) */ static const float coeff_0to8[] = { 0.143432, 0.144372, 0.147260, 0.152300, 0.159883, 0.170661, 0.185731, 0.207002, 0.238081, 0.286336, 0.366540, 0.501252, 0.699580, 0.906853, 1.000000, }; static const float coeff_8toinf[] = { 0.405687, 0.405664, 0.405601, 0.405494, 0.405349, 0.405164, 0.404945, 0.404692, 0.404413, 0.404107, 0.403782, 0.403439, 0.403086, 0.402724, 0.402359, 0.401995, 0.401637, 0.401287, 0.400951, 0.400631, 0.400332, 0.400055, 0.399805, 0.399582, 0.399391, 0.399231, 0.399106, 0.399012, 0.398998, 0.399001 }; /* * modified bessel function */ double bessel_i0(double x) { if (x < 0.) return bessel_i0(-x); if (x < 8.) return exp(x) * chebeval(x / 4. - 1., ARRAY_SIZE(coeff_0to8), coeff_0to8); return exp(x) * chebeval(16. / x - 1., ARRAY_SIZE(coeff_8toinf), coeff_8toinf) / sqrt(x); } bart-0.5.00/src/num/specfun.h000066400000000000000000000000471353046746100157400ustar00rootroot00000000000000 extern double bessel_i0(double x); bart-0.5.00/src/num/splines.c000066400000000000000000000214701353046746100157500ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include #include "splines.h" static long binomial(unsigned int n, unsigned int k) { long result = 1; for (unsigned int i = 1; i <= k; i++) result *= (n + 1 - i); for (unsigned int i = 1; i <= k; i++) result /= i; return result; } /* basis */ double bernstein(unsigned int n, unsigned int v, double x) { assert(v <= n); return binomial(n, v) * pow(x, v) * pow(1. - x, n - v); } static double lerp(double t, double a, double b) { return (1. - t) * a + t * b; } static void de_casteljau_step(unsigned int N, double out[static N], double t, const double coeff[static N + 1]) { for (unsigned int i = 0; i < N; i++) out[i] = lerp(t, coeff[i], coeff[i + 1]); } static double de_casteljau(double t, unsigned int N, const double coeff[static N + 1]) { if (0 == N) return coeff[0]; double coeff2[N]; de_casteljau_step(N, coeff2, t, coeff); return de_casteljau(t, N - 1, coeff2); } static void de_casteljau_split(double t, unsigned int N, double coeffA[static N + 1], double coeffB[static N + 1], const double coeff[static N + 1]) { coeffA[0] = coeff[0]; coeffB[N] = coeff[N]; if (0 == N) return; double coeff2[N]; de_casteljau_step(N, coeff2, t, coeff); de_casteljau_split(t, N - 1, coeffA + 1, coeffB, coeff2); } void bezier_split(double t, unsigned int N, double coeffA[static N + 1], double coeffB[static N + 1], const double coeff[static N + 1]) { de_casteljau_split(t, N, coeffA, coeffB, coeff); } double bezier_curve(double u, unsigned int N, const double k[static N + 1]) { return de_casteljau(u, N, k); } void bezier_increase_degree(unsigned int N, double coeff2[static N + 2], const double coeff[static N + 1]) { coeff2[0] = coeff[0]; for (unsigned int i = 1; i <= N; i++) coeff2[i] = lerp(i / (1. + N), coeff[i], coeff[i - 1]); coeff2[N + 1] = coeff[N]; } double bezier_surface(double u, double v, unsigned int N, unsigned int M, const double k[static N + 1][M + 1]) { double coeff[N + 1]; for (unsigned int i = 0; i <= N; i++) coeff[i] = bezier_curve(u, M, k[i]); return bezier_curve(v, N, coeff); } double bezier_patch(double u, double v, const double k[4][4]) { return bezier_surface(u, v, 3, 3, k); } static void cspline2bezier(double out[4], const double in[4]) { const double m[4][4] = { { 1., 1., 0., 0., }, { 0., 1./ 3., 0., 0., }, { 0., 0., 1., 1., }, { 0., 0., -1./3., 0., }, }; for (int i = 0; i < 4; i++) { out[i] = 0.; for (int j = 0; j < 4; j++) out[i] += m[j][i] * in[j]; } } // cubic hermite spline double cspline(double t, const double coeff[4]) { double coeff2[4]; cspline2bezier(coeff2, coeff); return bezier_curve(t, 3, coeff2); } static double frac(double u, double v) { if (0. == v) { // assert(0. == u); return 0.; } return u / v; } /* * bspline blending function of order p with n + 1 knots. i enumerates the basis. */ double bspline(unsigned int n, unsigned int i, unsigned int p, const double tau[static n + 1], double u) { assert(i + p < n); assert(tau[i] <= tau[i + 1]); assert((tau[0] <= u) && (u <= tau[n])); if (0 == p) return ((tau[i] <= u) && (u < tau[i + 1])) ? 1. : 0.; assert(tau[i] <= tau[i + p + 1]); double a = frac(u - tau[i], tau[i + p] - tau[i]); double b = frac(tau[i + p + 1] - u, tau[i + p + 1] - tau[i + 1]); return a * bspline(n, i, p - 1, tau, u) + b * bspline(n, i + 1, p - 1, tau, u); } double bspline_derivative(unsigned int n, unsigned int i, unsigned int p, const double tau[static n + 1], double x) { assert(p > 0); double a = frac(p, tau[i + p] - tau[i]); double b = frac(p, tau[i + p + 1] - tau[i + 1]); return a * bspline(n, i, p - 1, tau, x) - b * bspline(n, i + 1, p - 1, tau, x); } double nurbs(unsigned int n, unsigned int p, const double tau[static n + 1], const double coord[static n - p], const double w[static n - p], double x) { #if 0 double sum = 0.; double nrm = 0.; for (unsigned int i = 0; i < n + 0 - p; i++) { double b = bspline(n, i, p, tau, x); sum += w[i] * coord[i] * b; nrm += w[i] * b; } #else double coordw[n - p]; for (unsigned int i = 0; i < n + 0 - p; i++) coordw[i] = w[i] * coord[i]; double sum = bspline_curve(n, p, tau, coordw, x); double nrm = bspline_curve(n, p, tau, w, x); #endif return sum / nrm; } static void cox_deboor_step(unsigned int N, double out[static N], double x, unsigned int p, const double tau[static N + p + 1], const double coeff[static N + 1]) { unsigned int k = p - N + 1; for (unsigned int s = 0; s < N; s++) { double t = frac(x - tau[s + k], tau[s + p + 1] - tau[s + k]); out[s] = lerp(t, coeff[s], coeff[s + 1]); } } static double cox_deboor_i(double x, unsigned int N, unsigned int p, const double tau[static N + 1], const double coeff[static N + 1]) { if (0 == N) return coeff[0]; double coeff2[N]; cox_deboor_step(N, coeff2, x, p, tau, coeff); return cox_deboor_i(x, N - 1, p, tau, coeff2); } #if 0 static double cox_deboor_r(unsigned int n, unsigned int p, unsigned int k, unsigned int s, const double t2[static n + 1], const double v2[static n + 1 - p], double x) { if (0 == k) return v2[s]; double t = (x - t2[s]) / (t2[s + p - k + 1] - t2[s]); double a = cox_deboor_r(n, p, k - 1, s - 1, t2, v2, x); double b = cox_deboor_r(n, p, k - 1, s - 0, t2, v2, x); return lerp(t, a, b); } #endif static unsigned int find_span(unsigned int n, const double t[static n + 1], double x) { assert(x >= t[0]); unsigned int i = 0; while (x >= t[i]) i++; i--; return i; } static double cox_deboor(unsigned int n, unsigned int p, const double t[static n + 1], const double v[static n + 1 - p], double x) { int i = find_span(n, t, x); // return cox_deboor_r(n, p, p, p, t + i - p, v + i - p, x); return cox_deboor_i(x, p, p, t + i - p, v + i - p); } double bspline_curve(unsigned int n, unsigned int p, const double t[static n + 1], const double v[static n - p], double x) { return cox_deboor(n, p, t, v, x); } static void bspline_coeff_derivative(unsigned int n, unsigned int p, double t2[static n - 1], double v2[static n - p - 1], const double t[static n + 1], const double v[static n - p]) { for (unsigned int i = 1; i < n; i++) t2[i - 1] = t[i]; for (unsigned int i = 0; i < n - p - 1; i++) v2[i] = (float)p / (t[i + p + 1] - t[i + 1]) * (v[i + 1] - v[i]); } void bspline_coeff_derivative_n(unsigned int k, unsigned int n, unsigned int p, double t2[static n + 1 - 2 * k], double v2[static n - p - k], const double t[static n + 1], const double v[static n - p]) { if (0 == k) { for (unsigned int i = 0; i < n + 1; i++) t2[i] = t[i]; for (unsigned int i = 0; i < n - p; i++) v2[i] = v[i]; } else { double t1[n - 1]; double v1[n - p - 1]; bspline_coeff_derivative(n, p, t1, v1, t, v); bspline_coeff_derivative_n(k - 1, n - 1, p - 1, t2, v2, t1, v1); } } double bspline_curve_derivative(unsigned int k, unsigned int n, unsigned int p, const double t[static n + 1], const double v[static n - p], double x) { double t2[n + 1 - 2 * k]; double v2[n - p - k]; bspline_coeff_derivative_n(k, n, p, t2, v2, t, v); return cox_deboor(n - 2 * k, p - k, t2, v2, x); } static double newton_raphson(int iter, double x0, void* data, double (*fun)(void* data, double x), double (*der)(void* data, double x)) { return (0 == iter) ? x0 : newton_raphson(iter - 1, x0 - fun(data, x0) / der(data, x0), data, fun, der); } struct bspline_s { unsigned int n; unsigned int p; const double* t; const double* v; }; static double n_fun(void* _data, double x) { struct bspline_s* data = _data; return bspline_curve(data->n, data->p, data->t, data->v, x); } static double n_der(void* _data, double x) { struct bspline_s* data = _data; return bspline_curve_derivative(1, data->n, data->p, data->t, data->v, x); } double bspline_curve_zero(unsigned int n, unsigned int p, const double tau[static n + 1], const double v[static n - p]) { return newton_raphson(20, (tau[n] + tau[0]) / 2., &(struct bspline_s){ n, p, tau, v }, n_fun, n_der); } void bspline_knot_insert(double x, unsigned int n, unsigned int p, double t2[static n + 2], double v2[n - p + 1], const double tau[static n + 1], const double v[static n - p]) { unsigned int k = find_span(n, tau, x); // knots for (unsigned int i = 0; i <= k; i++) t2[i] = tau[i]; t2[k + 1] = x; for (unsigned int i = k + 1; i < n; i++) t2[i + 1] = tau[i]; unsigned int r = k - p + 1; unsigned int s = k; for (unsigned int i = 0; i < r; i++) v2[i] = v[i]; for (unsigned int i = r; i <= s; i++) { double a = (x - tau[i]) / (tau[i + p] - tau[i]); v2[i] = (1. - a) * v[i - 1] + a * v[i]; } for (unsigned int i = s; i < n - p; i++) v2[i + 1] = v[i]; } bart-0.5.00/src/num/splines.h000066400000000000000000000035001353046746100157470ustar00rootroot00000000000000 extern double bernstein(unsigned int n, unsigned int v, double x); extern double bezier_curve(double u, unsigned int N, const double k[static N + 1]); extern void bezier_split(double t, unsigned int N, double coeffA[static N + 1], double coeffB[static N + 1], const double coeff[static N + 1]); extern void bezier_increase_degree(unsigned int N, double coeff2[static N + 2], const double coeff[static N + 1]); extern double cspline(double t, const double coeff[4]); extern double bezier_surface(double u, double v, unsigned int N, unsigned int M, const double k[static N + 1][M + 1]); extern double bezier_patch(double u, double v, const double k[4][4]); extern double bspline(unsigned int n, unsigned int i, unsigned int p, const double tau[static n + 1], double x); extern double bspline_derivative(unsigned int n, unsigned int i, unsigned int p, const double tau[static n + 1], double x); extern double bspline_curve(unsigned int n, unsigned int p, const double t[static n + 1], const double v[static n - p], double x); extern double bspline_curve_derivative(unsigned int k, unsigned int n, unsigned int p, const double t[static n + 1], const double v[static n - p], double x); extern void bspline_coeff_derivative_n(unsigned int k, unsigned int n, unsigned int p, double t2[static n - 1], double v2[n - p - 2], const double t[static n + 1], const double v[static n - p]); extern double bspline_curve_zero(unsigned int n, unsigned int p, const double tau[static n + 1], const double v[static n - p]); extern void bspline_knot_insert(double x, unsigned int n, unsigned int p, double t2[static n + 2], double v2[n - p + 1], const double tau[static n + 1], const double v[static n - p]); extern double nurbs(unsigned int n, unsigned int p, const double tau[static n + 1], const double coord[static n - p], const double w[static n - p], double x); bart-0.5.00/src/num/vec3.c000066400000000000000000000025421353046746100151320ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include "vec3.h" void vec3_saxpy(vec3_t dst, const vec3_t src1, float alpha, const vec3_t src2) { for (unsigned int i = 0; i < 3; i++) dst[i] = src1[i] + alpha * src2[i]; } void vec3_sub(vec3_t dst, const vec3_t src1, const vec3_t src2) { vec3_saxpy(dst, src1, -1., src2); } void vec3_add(vec3_t dst, const vec3_t src1, const vec3_t src2) { vec3_saxpy(dst, src1, +1., src2); } void vec3_copy(vec3_t dst, const vec3_t src) { vec3_saxpy(dst, src, 0., src); } void vec3_clear(vec3_t dst) { vec3_saxpy(dst, dst, -1., dst); } float vec3_sdot(const vec3_t a, const vec3_t b) { float ret = 0.; for (unsigned int i = 0; i < 3; i++) ret += a[i] * b[i]; return ret; } float vec3_norm(const vec3_t x) { return sqrtf(vec3_sdot(x, x)); } void vec3_rot(vec3_t dst, const vec3_t src1, const vec3_t src2) { vec3_t tmp; tmp[0] = src1[1] * src2[2] - src1[2] * src2[1]; tmp[1] = src1[2] * src2[0] - src1[0] * src2[2]; tmp[2] = src1[0] * src2[1] - src1[1] * src2[0]; vec3_copy(dst, tmp); } void vec3_smul(vec3_t dst, const vec3_t src, float alpha) { vec3_saxpy(dst, (vec3_t){ 0., 0., 0. }, alpha, src); } bart-0.5.00/src/num/vec3.h000066400000000000000000000011071353046746100151330ustar00rootroot00000000000000 typedef float vec3_t[3]; extern void vec3_saxpy(vec3_t dst, const vec3_t src1, float alpha, const vec3_t src2); extern void vec3_sub(vec3_t dst, const vec3_t src1, const vec3_t src2); extern void vec3_add(vec3_t dst, const vec3_t src1, const vec3_t src2); extern void vec3_copy(vec3_t dst, const vec3_t src); extern void vec3_clear(vec3_t dst); extern float vec3_sdot(const vec3_t a, const vec3_t b); extern float vec3_norm(const vec3_t x); extern void vec3_rot(vec3_t dst, const vec3_t src1, const vec3_t src2); extern void vec3_smul(vec3_t dst, const vec3_t src, float alpha); bart-0.5.00/src/num/vecops.c000066400000000000000000000361241353046746100155740ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2011-2017 Martin Uecker * 2014 Frank Ong * 2014-2018 Jon Tamir * 2017 Sofia Dimoudi * * * This file defines basic operations on vectors of floats/complex floats * for operations on the CPU which are are used by higher level code * (mainly num/flpmath.c and num/italgos.c) to implement more complex * operations. The functions are exported by pointers stored in the * global variable cpu_ops of type struct vec_ops. Identical functions * are implemented for the GPU in gpukrnls.c. * */ #include #include #include #include #include "misc/misc.h" #include "misc/debug.h" #include "vecops.h" /** * Allocate memory for array of floats. * Note: be sure to pass 2*N if allocating for complex float * * @param N number of elements */ static float* allocate(long N) { assert(N >= 0); return xmalloc((size_t)N * sizeof(float)); } static void del(float* vec) { xfree(vec); } static void copy(long N, float* dst, const float* src) { for (long i = 0; i < N; i++) dst[i] = src[i]; } static void float2double(long N, double* dst, const float* src) { for (long i = 0; i < N; i++) dst[i] = src[i]; } static void double2float(long N, float* dst, const double* src) { for (long i = 0; i < N; i++) dst[i] = src[i]; } /* * Set vector to all-zeros * * @param N vector length * @param vec vector */ static void clear(long N, float* vec) { for (long i = 0; i < N; i++) vec[i] = 0.; } static double dot(long N, const float* vec1, const float* vec2) { double res = 0.; for (long i = 0; i < N; i++) res += vec1[i] * vec2[i]; //res = fma((double)vec1[i], (double)vec2[i], res); return res; } /** * Compute l2 norm of vec * * @param N vector length * @param vec vector */ static double norm(long N, const float* vec) { double res = 0.; for (long i = 0; i < N; i++) res += vec[i] * vec[i]; //res = fma((double)vec[i], (double)vec[i], res); return sqrt(res); } /** * Compute l1 norm of vec * * @param N vector length * @param vec vector */ static double asum(long N, const float* vec) { double res = 0.; for (long i = 0; i < N; i++) res += fabsf(vec[i]); return res; } /** * Compute l1 norm of complex vec * * @param N vector length * @param vec vector */ static double zl1norm(long N, const complex float* vec) { double res = 0.; for (long i = 0; i < N; i++) res += cabsf(vec[i]); return res; } // we should probably replace asum and zl1norm static void zsum(long N, complex float* vec) { complex float res = 0.; for (long i = 0; i < N; i++) res += vec[i]; vec[0] = res; } static void axpbz(long N, float* dst, const float a1, const float* src1, const float a2, const float* src2) { for (long i = 0; i < N; i++) dst[i] = a1 * src1[i] + a2 * src2[i]; } static void axpy(long N, float* dst, float alpha, const float* src) { axpbz(N, dst, 1., dst, alpha, src); //dst[i] = fmaf(alpha, src[i], dst[i]); } static void xpay(long N, float beta, float* dst, const float* src) { axpbz(N, dst, beta, dst, 1., src); //dst[i] = fmaf(beta, dst[i], src[i]); } static void smul(long N, float alpha, float* dst, const float* src) { axpbz(N, dst, 0., src, alpha, src); //dst[i] = fmaf(alpha, src[i], 0.f); } static void add(long N, float* dst, const float* src1, const float* src2) { #if 1 if (dst == src1) { for (long i = 0; i < N; i++) dst[i] += src2[i]; } else #endif for (long i = 0; i < N; i++) dst[i] = src1[i] + src2[i]; } static void sub(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] = src1[i] - src2[i]; } static void mul(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] = src1[i] * src2[i]; } static void vec_div(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) //dst[i] = src1[i] / src2[i]; dst[i] = (src2[i] == 0) ? 0.f : src1[i] / src2[i]; } static void fmac(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] += src1[i] * src2[i]; //dst[i] = fmaf(src1[i], src2[i], dst[i]); } static void fmac2(long N, double* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] += src1[i] * src2[i]; } static void zsmul(long N, complex float val, complex float* dst, const complex float* src1) { for (long i = 0; i < N; i++) dst[i] = src1[i] * val; } static void zmul(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = src1[i] * src2[i]; } static void zdiv(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = (src2[i] == 0) ? 0.f : src1[i] / src2[i]; } static void zpow(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = cpowf(src1[i], src2[i]); } static void zfmac(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] += src1[i] * src2[i]; } static void zfmac2(long N, complex double* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] += src1[i] * src2[i]; } static void zmulc(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = src1[i] * conjf(src2[i]); } static void zfmacc(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] += src1[i] * conjf(src2[i]); } static void zfmacc2(long N, complex double* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] += src1[i] * conjf(src2[i]); } static void zconj(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = conjf(src[i]); } static void zcmp(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = (src1[i] == src2[i]) ? 1. : 0.; } static void zdiv_reg(long N, complex float* dst, const complex float* src1, const complex float* src2, complex float lambda) { for (long i = 0; i < N; i++) dst[i] = (src2[i] == 0) ? 0.f : src1[i] / (lambda + src2[i]); } static void zphsr(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) { float s = cabsf(src[i]); /* Note: the comparison (0 == src[i]) is not enough with `--fast-math` * with gcc 4.4.3 (but seems to work for 4.7.3, different computer) * Test: * complex float a = FLT_MIN; * complex float c = a / cabsf(a); * assert(!(isnan(creal(c)) || isnan(cimag(c)))); */ dst[i] = (0. == s) ? 1. : (src[i] / s); } } static void zexp(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = cexpf(src[i]); } static void zexpj(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = cexpf(1.I * src[i]); } static void zarg(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = cargf(src[i]); } static void zabs(long N, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = cabsf(src[i]); } static void zmax(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = (crealf(src1[i]) > crealf(src2[i])) ? src1[i] : src2[i]; } static void max(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] = MAX(src1[i], src2[i]); } static void smax(long N, float val, float* dst, const float* src1) { for (long i = 0; i < N; i++) dst[i] = MAX(src1[i], val); } static void min(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] = MIN(src1[i], src2[i]); } static void zsmax(long N, float val, complex float* dst, const complex float* src) { for (long i = 0; i < N; i++) dst[i] = MAX(crealf(src[i]), val); } static void vec_pow(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] = powf(src1[i], src2[i]); } static void vec_sqrt(long N, float* dst, const float* src) { for (long i = 0; i < N; i++) dst[i] = sqrtf(src[i]); } static void vec_zle(long N, complex float* dst, const complex float* src1, const complex float* src2) { for (long i = 0; i < N; i++) dst[i] = (crealf(src1[i]) <= crealf(src2[i])); } static void vec_le(long N, float* dst, const float* src1, const float* src2) { for (long i = 0; i < N; i++) dst[i] = (src1[i] <= src2[i]); } /** * Step (1) of soft thesholding, y = ST(x, lambda). * Only computes the residual, resid = MAX( (abs(x) - lambda)/abs(x)), 0 ) * * @param N number of elements * @param lambda threshold parameter * @param d pointer to destination, resid * @param x pointer to input */ static void zsoftthresh_half(long N, float lambda, complex float* d, const complex float* x) { for (long i = 0; i < N; i++) { float norm = cabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (red / norm) : 0.; } } static void zsoftthresh(long N, float lambda, complex float* d, const complex float* x) { for (long i = 0; i < N; i++) { float norm = cabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (red / norm) * x[i]: 0.; } } static void softthresh_half(long N, float lambda, float* d, const float* x) { for (long i = 0; i < N; i++) { float norm = fabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (red / norm) : 0.; } } static void softthresh(long N, float lambda, float* d, const float* x) { for (long i = 0; i < N; i++) { float norm = fabsf(x[i]); float red = norm - lambda; d[i] = (red > 0.) ? (red / norm) * x[i] : 0.; } } /** * Return the absolute value of the kth largest array element * To be used for hard thresholding * * @param N number of elements * @param k the sorted element index to pick * @param ar the input complex array * * @returns the absolute value of the kth largest array element. * */ static float klargest_complex_partsort( unsigned int N, unsigned int k, const complex float* ar) { assert(k <= N); complex float* tmp = (complex float*)xmalloc(N * sizeof(complex float)); copy(2 * N, (float*)tmp, (float*)ar); float thr = quickselect_complex(tmp, N, k); xfree(tmp); return thr; } /** * Hard thesholding, y = HT(x, thr). * computes the thresholded vector, y = x * (abs(x) >= t(kmax)) * * @param N number of elements * @param k threshold parameter, index of kth largest element of sorted x * @param d pointer to destination, y * @param x pointer to input */ static void zhardthresh(long N, unsigned int k, complex float* d, const complex float* x) { float thr = klargest_complex_partsort(N, k, x); for (long i = 0; i < N; i++) { float norm = cabsf(x[i]); d[i] = (norm > thr) ? x[i] : 0.; } } /** * Hard thesholding mask, m = HS(x, thr). * computes the non-zero complex support vector, m = 1.0 * (abs(x) >= t(kmax)) * This mask should be applied by complex multiplication. * * @param N number of elements * @param k threshold parameter, index of kth largest element of sorted x * @param d pointer to destination * @param x pointer to input */ static void zhardthresh_mask(long N, unsigned int k, complex float* d, const complex float* x) { float thr = klargest_complex_partsort(N, k, x); for (long i = 0; i < N; i++) { float norm = cabsf(x[i]); d[i] = (norm > thr) ? 1. : 0.; } } static void swap(long N, float* a, float* b) { for (long i = 0; i < N; i++) { float tmp = a[i]; a[i] = b[i]; b[i] = tmp; } } // identical copy in num/fft.c static double fftmod_phase(long length, int j) { long center1 = length / 2; double shift = (double)center1 / (double)length; return ((double)j - (double)center1 / 2.) * shift; } static complex double fftmod_phase2(long n, int j, bool inv, double phase) { phase += fftmod_phase(n, j); double rem = phase - floor(phase); double sgn = inv ? -1. : 1.; #if 1 if (rem == 0.) return 1.; if (rem == 0.5) return -1.; if (rem == 0.25) return 1.i * sgn; if (rem == 0.75) return -1.i * sgn; #endif return cexp(M_PI * 2.i * sgn * rem); } static void zfftmod(long N, complex float* dst, const complex float* src, unsigned int n, bool inv, double phase) { #if 1 if (0 == n % 2) { complex float ph = fftmod_phase2(n, 0, inv, phase); for (long i = 0; i < N; i++) for (unsigned int j = 0; j < n; j++) dst[i * n + j] = src[i * n + j] * ((0 == j % 2) ? ph : -ph); return; } #endif for (long i = 0; i < N; i++) for (unsigned int j = 0; j < n; j++) dst[i * n + j] = src[i * n + j] * fftmod_phase2(n, j, inv, phase); } /* * If you add functions here, please also add to gpuops.c/gpukrnls.cu */ const struct vec_ops cpu_ops = { .float2double = float2double, .double2float = double2float, .dot = dot, .asum = asum, .zsum = zsum, .zl1norm = zl1norm, .add = add, .sub = sub, .mul = mul, .div = vec_div, .fmac = fmac, .fmac2 = fmac2, .smul = smul, .axpy = axpy, .pow = vec_pow, .sqrt = vec_sqrt, .zle = vec_zle, .le = vec_le, .zmul = zmul, .zdiv = zdiv, .zfmac = zfmac, .zfmac2 = zfmac2, .zmulc = zmulc, .zfmacc = zfmacc, .zfmacc2 = zfmacc2, .zsmax = zsmax, .zsmul = zsmul, .zpow = zpow, .zphsr = zphsr, .zconj = zconj, .zexpj = zexpj, .zexp = zexp, .zarg = zarg, .zabs = zabs, .zcmp = zcmp, .zdiv_reg = zdiv_reg, .zfftmod = zfftmod, .zmax = zmax, .smax = smax, .max = max, .min = min, .zsoftthresh = zsoftthresh, .zsoftthresh_half = zsoftthresh_half, .softthresh = softthresh, .softthresh_half = softthresh_half, .zhardthresh = zhardthresh, .zhardthresh_mask = zhardthresh_mask, }; // defined in iter/vec.h struct vec_iter_s { float* (*allocate)(long N); void (*del)(float* x); void (*clear)(long N, float* x); void (*copy)(long N, float* a, const float* x); void (*swap)(long N, float* a, float* x); double (*norm)(long N, const float* x); double (*dot)(long N, const float* x, const float* y); void (*sub)(long N, float* a, const float* x, const float* y); void (*add)(long N, float* a, const float* x, const float* y); void (*smul)(long N, float alpha, float* a, const float* x); void (*xpay)(long N, float alpha, float* a, const float* x); void (*axpy)(long N, float* a, float alpha, const float* x); void (*axpbz)(long N, float* out, const float a, const float* x, const float b, const float* z); void (*zmul)(long N, complex float* dst, const complex float* src1, const complex float* src2); }; extern const struct vec_iter_s cpu_iter_ops; const struct vec_iter_s cpu_iter_ops = { .allocate = allocate, .del = del, .clear = clear, .copy = copy, .dot = dot, .norm = norm, .axpy = axpy, .xpay = xpay, .axpbz = axpbz, .smul = smul, .add = add, .sub = sub, .swap = swap, .zmul = zmul, }; bart-0.5.00/src/num/vecops.h000066400000000000000000000103531353046746100155750ustar00rootroot00000000000000/* Copyright 2013-2017. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * Copyright 2017. University of Oxford. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __VECOPS_H #define __VECOPS_H extern const struct vec_ops cpu_ops; struct vec_ops { void (*float2double)(long N, double* dst, const float* src); void (*double2float)(long N, float* dst, const double* src); double (*dot)(long N, const float* vec1, const float* vec2); double (*asum)(long N, const float* vec); void (*zsum)(long N, _Complex float* vec); double (*zl1norm)(long N, const _Complex float* vec); void (*axpy)(long N, float* a, float alpha, const float* x); void (*axpbz)(long N, float* out, const float a, const float* x, const float b, const float* z); void (*pow)(long N, float* dst, const float* src1, const float* src2); void (*sqrt)(long N, float* dst, const float* src); void (*zle)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*le)(long N, float* dst, const float* src1, const float* src2); void (*add)(long N, float* dst, const float* src1, const float* src2); void (*sub)(long N, float* dst, const float* src1, const float* src2); void (*mul)(long N, float* dst, const float* src1, const float* src2); void (*div)(long N, float* dst, const float* src1, const float* src2); void (*fmac)(long N, float* dst, const float* src1, const float* src2); void (*fmac2)(long N, double* dst, const float* src1, const float* src2); void (*smul)(long N, float alpha, float* dst, const float* src1); void (*zmul)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zdiv)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zfmac)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zfmac2)(long N, _Complex double* dst, const _Complex float* src1, const _Complex float* src2); void (*zmulc)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zfmacc)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zfmacc2)(long N, _Complex double* dst, const _Complex float* src1, const _Complex float* src2); void (*zsmul)(long N, _Complex float val, _Complex float* dst, const _Complex float* src1); void (*zpow)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zphsr)(long N, _Complex float* dst, const _Complex float* src); void (*zconj)(long N, _Complex float* dst, const _Complex float* src); void (*zexpj)(long N, _Complex float* dst, const _Complex float* src); void (*zexp)(long N, _Complex float* dst, const _Complex float* src); void (*zarg)(long N, _Complex float* dst, const _Complex float* src); void (*zabs)(long N, _Complex float* dst, const _Complex float* src); void (*zcmp)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zdiv_reg)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2, _Complex float lambda); void (*zfftmod)(long N, _Complex float* dst, const _Complex float* src, unsigned int n, _Bool inv, double phase); void (*zmax)(long N, _Complex float* dst, const _Complex float* src1, const _Complex float* src2); void (*zsmax)(long N, float alpha, _Complex float* dst, const _Complex float* src); void (*smax)(long N, float val, float* dst, const float* src1); void (*max)(long N, float* dst, const float* src1, const float* src2); void (*min)(long N, float* dst, const float* src1, const float* src2); void (*zsoftthresh_half)(long N, float lambda, _Complex float* dst, const _Complex float* src); void (*zsoftthresh)(long N, float lambda, _Complex float* dst, const _Complex float* src); void (*softthresh_half)(long N, float lambda, float* dst, const float* src); void (*softthresh)(long N, float lambda, float* dst, const float* src); // void (*swap)(long N, float* a, float* b); void (*zhardthresh)(long N, unsigned int k, _Complex float* d, const _Complex float* x); void (*zhardthresh_mask)(long N, unsigned int k, _Complex float* d, const _Complex float* x); }; #endif bart-0.5.00/src/num/wavelet.c000066400000000000000000000153531353046746100157450ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2013 Martin Uecker * * * Implementation of CDF97 wavelets. * * Ingrid Daubechies and Wil Sweldens, Factoring wavelet transforms into * lifting steps. Journal of Fourier Analysis and Applications 1998, * Volume 4, Issue 3, pp 247-269 * */ #include #include #include #include "num/multind.h" //#include "num/parallel.h" #ifdef USE_CUDA #include "num/gpuops.h" #ifdef BERKELEY_SVN #include "num/wlcuda.h" #endif #endif #include "wavelet.h" const float a[4] = { -1.586134342, -0.05298011854, 0.8829110762, 0.4435068522 }; const float scale = 1.149604398; /** * This is designed to work for every n. * For odd n, we split n = a + b with * a = b + 1 where a is the number of * coarse coefficients. This splitting is * implicit by putting the first * value into the coarse coefficients. */ static void predict(int n, float a, int str, float* x) { for (int i = 1; i < n - 1; i += 2) x[i * str] += a * (x[(i - 1) * str] + x[(i + 1) * str]); if (0 == n % 2) x[(n - 1) * str] += a * (x[(n - 2) * str] + x[0]); // periodic // x[(n - 1) * str] += 2. * a * x[(n - 2) * str]; // non-periodic } static void update(int n, float a, int str, float* x) { for (int i = 2; i < n - 1; i += 2) x[i * str] += a * (x[(i - 1) * str] + x[(i + 1) * str]); if (0 == n % 2) // +-+-+- x[0] += a * (x[(n - 1) * str] + x[1 * str]); // periodic // x[0] += 2. * a * x[1 * str]; // non-periodic else { // +-+-+ x[0] += 2. * a * x[1 * str]; x[(n - 1) * str] += 2. * a * x[(n - 2) * str]; } } static void cdf97(int n, int str, float* x) { predict(n, a[0], str, x); update(n, a[1], str, x); predict(n, a[2], str, x); update(n, a[3], str, x); for (int i = 0; i < n; i++) x[i * str] *= (0 == i % 2) ? scale : (1. / scale); } static void icdf97(int n, int str, float* x) { for (int i = 0; i < n; i++) x[i * str] *= (0 == i % 2) ? (1. / scale) : scale; update(n, -a[3], str, x); predict(n, -a[2], str, x); update(n, -a[1], str, x); predict(n, -a[0], str, x); } static long num_coeff(long n) { return n / 2; } static long num_scale(long n) { return n - num_coeff(n); } static void resort(int n, int str, float* src) { float tmp[n]; for (int i = 0; i < num_scale(n); i++) tmp[i] = src[(i * 2 + 0) * str]; for (int i = 0; i < num_coeff(n); i++) tmp[num_scale(n) + i] = src[(i * 2 + 1) * str]; for (int i = 0; i < n; i++) src[i * str] = tmp[i]; } static void iresort(int n, int str, float* src) { float tmp[n]; for (int i = 0; i < num_scale(n); i++) tmp[i * 2 + 0] = src[i * str]; for (int i = 0; i < num_coeff(n); i++) tmp[i * 2 + 1] = src[(num_scale(n) + i) * str]; for (int i = 0; i < n; i++) src[i * str] = tmp[i]; } static NESTED(void, cdf97_line, (long n, long str, void* ptr)) { cdf97(n, str / 4, ptr); resort(n, str / 4, ptr); }; static NESTED(void, icdf97_line, (long n, long str, void* ptr)) { iresort(n, str / 4, ptr); icdf97(n, str / 4, ptr); }; static NESTED(void, cdf97_line_nosort, (long n, long str, void* ptr)) { #ifdef USE_CUDA if (cuda_ondevice(ptr)) #ifdef BERKELEY_SVN cuda_cdf97(n, str / 4, ptr); #else assert(0); #endif else #endif cdf97(n, str / 4, ptr); }; static NESTED(void, icdf97_line_nosort, (long n, long str, void* ptr)) { #ifdef USE_CUDA if (cuda_ondevice(ptr)) #ifdef BERKELEY_SVN cuda_icdf97(n, str / 4, ptr); #else assert(0); #endif else #endif icdf97(n, str / 4, ptr); }; void md_wavtrafo2(int D, const long dims[D], unsigned int flags, const long strs[D], void* ptr, md_trafo_fun_t fun, bool inv, bool nosort) { if (0 == flags) return; bool rec = true; for (int i = 0; i < D; i++) { if (1 == dims[i]) flags = MD_CLEAR(flags, i); if (MD_IS_SET(flags, i)) rec &= (dims[i] > 32); } if (!inv) md_septrafo2(D, dims, flags, strs, ptr, fun); //md_parallel_septrafo2(D, dims, flags, strs, ptr, fun); if (rec) { long dims2[D]; md_select_dims(D, ~0, dims2, dims); for (int i = 0; i < D; i++) if (MD_IS_SET(flags, i)) dims2[i] = num_scale(dims[i]); long strs2[D]; md_copy_strides(D, strs2, strs); for (int i = 0; i < D; i++) if (nosort && (MD_IS_SET(flags, i))) strs2[i] *= 2; md_wavtrafo2(D, dims2, flags, strs2, ptr, fun, inv, nosort); } if (inv) md_septrafo2(D, dims, flags, strs, ptr, fun); //md_parallel_septrafo2(D, dims, flags, strs, ptr, fun, NULL); } void md_wavtrafo(int D, const long dims[D], unsigned int flags, void* ptr, size_t size, md_trafo_fun_t fun, bool inv, bool nosort) { long strs[D]; md_calc_strides(D, strs, dims, size); md_wavtrafo2(D, dims, flags, strs, ptr, fun, inv, nosort); } void md_wavtrafoz2(int D, const long dims[D], unsigned int flags, const long strs[D], complex float* x, md_trafo_fun_t fun, bool inv, bool nosort) { long dims2[D + 1]; dims2[0] = 2; // complex float md_copy_dims(D, dims2 + 1, dims); long strs2[D + 1]; strs2[0] = sizeof(float); md_copy_strides(D, strs2 + 1, strs); md_wavtrafo2(D + 1, dims2, flags << 1, strs2, (void*)x, fun, inv, nosort); } void md_wavtrafoz(int D, const long dims[D], unsigned int flags, complex float* ptr, md_trafo_fun_t fun, bool inv, bool nosort) { long strs[D]; md_calc_strides(D, strs, dims, sizeof(complex float)); md_wavtrafoz2(D, dims, flags, strs, ptr, fun, inv, nosort); } void md_cdf97z(int D, const long dims[D], unsigned int flags, complex float* data) { md_wavtrafoz(D, dims, flags, data, cdf97_line_nosort, false, true); } void md_icdf97z(int D, const long dims[D], unsigned int flags, complex float* data) { md_wavtrafoz(D, dims, flags, data, icdf97_line_nosort, true, true); } void md_cdf97z2(int D, const long dims[D], unsigned int flags, const long strs[D], complex float* data) { md_wavtrafoz2(D, dims, flags, strs, data, cdf97_line_nosort, false, true); } void md_icdf97z2(int D, const long dims[D], unsigned int flags, const long strs[D], complex float* data) { md_wavtrafoz2(D, dims, flags, strs, data, icdf97_line_nosort, true, true); } // FIXME: slow void md_resortz(int D, const long dims[D], unsigned int flags, complex float* data) { md_wavtrafoz(D, dims, flags, data, icdf97_line_nosort, true, true); md_wavtrafoz(D, dims, flags, data, cdf97_line, false, false); } void md_iresortz(int D, const long dims[D], unsigned int flags, complex float* data) { md_wavtrafoz(D, dims, flags, data, icdf97_line, true, false); md_wavtrafoz(D, dims, flags, data, cdf97_line_nosort, false, true); } #if 0 const float d4[6] = { -sqrt(3.), sqrt(3.) / 4., -(2. - sqrt(3.)) / 4., 1., sqrt(2. + sqrt(3.)), sqrt(2. - sqrt(3.)) }; static void d4update(int n, float x[n]) { } void deb4 #endif bart-0.5.00/src/num/wavelet.h000066400000000000000000000030331353046746100157420ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "num/multind.h" #include "misc/cppwrap.h" extern void md_wavtrafo2(int D, const long dims[__VLA(D)], unsigned int flags, const long strs[__VLA(D)], void* ptr, md_trafo_fun_t fun, _Bool inv, _Bool nosort); extern void md_wavtrafo(int D, const long dims[__VLA(D)], unsigned int flags, void* ptr, size_t size, md_trafo_fun_t fun, _Bool inv, _Bool nosort); extern void md_wavtrafoz2(int D, const long dims[__VLA(D)], unsigned int flags, const long strs[__VLA(D)], _Complex float* x, md_trafo_fun_t fun, _Bool inv, _Bool nosort); extern void md_wavtrafoz(int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* ptr, md_trafo_fun_t fun, _Bool inv, _Bool nosort); extern void md_cdf97z(int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* data); extern void md_icdf97z(int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* data); extern void md_cdf97z2(int D, const long dims[__VLA(D)], unsigned int flags, const long strs[__VLA(D)], _Complex float* data); extern void md_icdf97z2(int D, const long dims[__VLA(D)], unsigned int flags, const long strs[__VLA(D)], _Complex float* data); extern void md_resortz(int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* data); extern void md_iresortz(int D, const long dims[__VLA(D)], unsigned int flags, _Complex float* data); #include "misc/cppwrap.h" bart-0.5.00/src/ones.c000066400000000000000000000021051353046746100144320ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2014 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" static const char usage_str[] = "dims dim1 ... dimn name"; static const char help_str[] = "Create an array filled with ones with {dims} dimensions of size {dim1} to {dimn}.\n"; int main_ones(int argc, char* argv[]) { mini_cmdline(&argc, argv, -3, usage_str, help_str); num_init(); int N = atoi(argv[1]); assert(N >= 0); assert(argc == 3 + N); long dims[N]; for (int i = 0; i < N; i++) { dims[i] = atoi(argv[2 + i]); assert(dims[i] >= 1); } complex float* x = create_cfl(argv[2 + N], N, dims); md_zfill(N, dims, x, 1.); unmap_cfl(N, dims, x); return 0; } bart-0.5.00/src/pattern.c000066400000000000000000000024541353046746100151520ustar00rootroot00000000000000/* Copyright 2013, 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2013 Martin Uecker * 2016 Jonathan Tamir */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/opts.h" static const char usage_str[] = " "; static const char help_str[] = "Compute sampling pattern from kspace\n"; int main_pattern(int argc, char* argv[]) { unsigned int flags = COIL_FLAG; const struct opt_s opts[] = { OPT_UINT('s', &flags, "bitmask", "Squash dimensions selected by bitmask"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int N = DIMS; long in_dims[N]; long out_dims[N]; complex float* kspace = load_cfl(argv[1], N, in_dims); md_select_dims(N, ~flags, out_dims, in_dims); complex float* pattern = create_cfl(argv[2], N, out_dims); estimate_pattern(N, in_dims, flags, pattern, kspace); unmap_cfl(N, in_dims, kspace); unmap_cfl(N, out_dims, pattern); return 0; } bart-0.5.00/src/phantom.c000066400000000000000000000056551353046746100151510ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013, 2015 Martin Uecker */ #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "simu/phantom.h" static const char usage_str[] = ""; static const char help_str[] = "Image and k-space domain phantoms."; int main_phantom(int argc, char* argv[]) { bool kspace = false; bool d3 = false; int sens = 0; int osens = -1; int xdim = -1; int geo = 0; bool out_sens = false; bool tecirc = false; bool circ = false; const char* traj = NULL; long dims[DIMS] = { [0 ... DIMS - 1] = 1 }; dims[0] = 128; dims[1] = 128; dims[2] = 1; const struct opt_s opts[] = { OPT_INT('s', &sens, "nc", "nc sensitivities"), OPT_INT('S', &osens, "", "Output nc sensitivities"), OPT_SET('k', &kspace, "k-space"), OPT_STRING('t', &traj, "file", "trajectory"), OPT_SET('c', &circ, "()"), OPT_SET('m', &tecirc, "()"), OPT_INT('x', &xdim, "n", "dimensions in y and z"), OPT_INT('G', &geo, "n=1,2", "Geometric object phantom"), OPT_SET('3', &d3, "3D"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); if (tecirc) { circ = true; dims[TE_DIM] = 32; } if (-1 != osens) { out_sens = true; sens = osens; } if (-1 != xdim) dims[0] = dims[1] = xdim; if (d3) dims[2] = dims[0]; long sdims[DIMS]; complex float* samples = NULL; if (NULL != traj) { samples = load_cfl(traj, DIMS, sdims); dims[0] = 1; dims[1] = sdims[1]; dims[2] = sdims[2]; } if (sens) dims[3] = sens; complex float* out = create_cfl(argv[1], DIMS, dims); if (out_sens) { assert(NULL == traj); assert(!kspace); calc_sens(dims, out); } else if (circ) { assert(NULL == traj); if (1 < dims[TE_DIM]) { assert(!d3); calc_moving_circ(dims, out, kspace); } else { (d3 ? calc_circ3d : calc_circ)(dims, out, kspace); // calc_ring(dims, out, kspace); } } else if (geo > 0) { if (geo > 2) error("geometric phantom: invalid geometry"); if (d3) error("geometric phantom: no 3D mode"); if (NULL == samples) { calc_geo_phantom(dims, out, kspace, geo); } else { dims[0] = 3; calc_geo_phantom_noncart(dims, out, samples, geo); dims[0] = 1; } } else { //assert(1 == dims[COIL_DIM]); if (NULL == samples) { (d3 ? calc_phantom3d : calc_phantom)(dims, out, kspace); } else { dims[0] = 3; (d3 ? calc_phantom3d_noncart : calc_phantom_noncart)(dims, out, samples); dims[0] = 1; } } if (NULL != traj) free((void*)traj); if (NULL != samples) unmap_cfl(3, sdims, samples); unmap_cfl(DIMS, dims, out); return 0; } bart-0.5.00/src/pics.c000066400000000000000000000440001353046746100144240ustar00rootroot00000000000000/* Copyright 2013-2018. The Regents of the University of California. * Copyright 2015-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2014-2016 Frank Ong * 2014-2018 Jon Tamir * */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "num/ops_p.h" #include "num/ops.h" #include "iter/misc.h" #include "iter/monitor.h" #include "linops/linop.h" #include "linops/fmac.h" #include "linops/sampling.h" #include "linops/someops.h" #include "noncart/nufft.h" #include "sense/recon.h" #include "sense/model.h" #include "sense/optcom.h" #include "misc/debug.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "grecon/optreg.h" #include "grecon/italgo.h" #include "num/iovec.h" #include "num/ops.h" static const char usage_str[] = " "; static const char help_str[] = "Parallel-imaging compressed-sensing reconstruction."; static const struct linop_s* sense_nc_init(const long max_dims[DIMS], const long map_dims[DIMS], const complex float* maps, const long ksp_dims[DIMS], const long traj_dims[DIMS], const complex float* traj, struct nufft_conf_s conf, const long wgs_dims[DIMS], const complex float* weights, const long basis_dims[DIMS], const complex float* basis, struct operator_s** precond_op, bool sms) { long coilim_dims[DIMS]; long img_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, coilim_dims, max_dims); md_select_dims(DIMS, ~COIL_FLAG, img_dims, max_dims); long ksp_dims2[DIMS]; md_copy_dims(DIMS, ksp_dims2, ksp_dims); ksp_dims2[COEFF_DIM] = max_dims[COEFF_DIM]; //ksp_dims2[TE_DIM] = 1; debug_print_dims(DP_INFO, DIMS, ksp_dims2); debug_print_dims(DP_INFO, DIMS, coilim_dims); const struct linop_s* fft_op = nufft_create2(DIMS, ksp_dims2, coilim_dims, traj_dims, traj, wgs_dims, weights, basis_dims, basis, conf); const struct linop_s* maps_op = maps2_create(coilim_dims, map_dims, img_dims, maps); if (sms) { /** * Apply Fourier encoding in image space (after coil * sensitivity weighting but before NUFFT). */ const struct linop_s* fft_slice = linop_fft_create(DIMS, coilim_dims, SLICE_FLAG); fft_op = linop_chain_FF(fft_slice, fft_op); } const struct linop_s* lop = linop_chain_FF(maps_op, fft_op); //precond_op[0] = (struct operator_s*) nufft_precond_create( fft_op ); precond_op[0] = NULL; return lop; } int main_pics(int argc, char* argv[]) { // Initialize default parameters struct sense_conf conf = sense_defaults; float bpsense_eps = -1.; unsigned int shift_mode = 0; bool randshift = true; bool overlapping_blocks = false; unsigned int maxiter = 30; float step = -1.; // Start time count double start_time = timestamp(); // Read input options struct nufft_conf_s nuconf = nufft_conf_defaults; nuconf.toeplitz = true; nuconf.lowmem = false; float restrict_fov = -1.; const char* pat_file = NULL; const char* traj_file = NULL; bool scale_im = false; bool eigen = false; float scaling = 0.; // Simultaneous Multi-Slice bool sms = false; unsigned int llr_blk = 8; const char* image_truth_file = NULL; bool im_truth = false; const char* image_start_file = NULL; bool warm_start = false; const char* basis_file = NULL; struct admm_conf admm = { false, false, false, iter_admm_defaults.rho, iter_admm_defaults.maxitercg }; enum algo_t algo = ALGO_DEFAULT; bool hogwild = false; bool fast = false; unsigned int gpun = 0; struct opt_reg_s ropts; opt_reg_init(&ropts); unsigned int loop_flags = 0u; const struct opt_s opts[] = { { 'l', true, opt_reg, &ropts, "1/-l2\t\ttoggle l1-wavelet or l2 regularization." }, OPT_FLOAT('r', &ropts.lambda, "lambda", "regularization parameter"), { 'R', true, opt_reg, &ropts, " :A:B:C\tgeneralized regularization options (-Rh for help)" }, OPT_SET('c', &conf.rvc, "real-value constraint"), OPT_FLOAT('s', &step, "step", "iteration stepsize"), OPT_UINT('i', &maxiter, "iter", "max. number of iterations"), OPT_STRING('t', &traj_file, "file", "k-space trajectory"), OPT_CLEAR('n', &randshift, "disable random wavelet cycle spinning"), OPT_SET('N', &overlapping_blocks, "do fully overlapping LLR blocks"), OPT_SET('g', &conf.gpu, "use GPU"), OPT_UINT('G', &gpun, "gpun", "use GPU device gpun"), OPT_STRING('p', &pat_file, "file", "pattern or weights"), OPT_SELECT('I', enum algo_t, &algo, ALGO_IST, "select IST"), OPT_UINT('b', &llr_blk, "blk", "Lowrank block size"), OPT_SET('e', &eigen, "Scale stepsize based on max. eigenvalue"), OPT_SET('H', &hogwild, "(hogwild)"), OPT_SET('D', &admm.dynamic_rho, "(ADMM dynamic step size)"), OPT_SET('F', &fast, "(fast)"), OPT_SET('J', &admm.relative_norm, "(ADMM residual balancing)"), OPT_STRING('T', &image_truth_file, "file", "(truth file)"), OPT_STRING('W', &image_start_file, "", "Warm start with "), OPT_INT('d', &debug_level, "level", "Debug level"), OPT_INT('O', &conf.rwiter, "rwiter", "(reweighting)"), OPT_FLOAT('o', &conf.gamma, "gamma", "(reweighting)"), OPT_FLOAT('u', &admm.rho, "rho", "ADMM rho"), OPT_UINT('C', &admm.maxitercg, "iter", "ADMM max. CG iterations"), OPT_FLOAT('q', &conf.cclambda, "cclambda", "(cclambda)"), OPT_FLOAT('f', &restrict_fov, "rfov", "restrict FOV"), OPT_SELECT('m', enum algo_t, &algo, ALGO_ADMM, "select ADMM"), OPT_FLOAT('w', &scaling, "val", "inverse scaling of the data"), OPT_SET('S', &scale_im, "re-scale the image after reconstruction"), OPT_UINT('L', &loop_flags, "flags", "batch-mode"), OPT_SET('K', &nuconf.pcycle, "randshift for NUFFT"), OPT_STRING('B', &basis_file, "file", "temporal (or other) basis"), OPT_FLOAT('P', &bpsense_eps, "eps", "Basis Pursuit formulation, || y- Ax ||_2 <= eps"), OPT_SELECT('a', enum algo_t, &algo, ALGO_PRIDU, "select Primal Dual"), OPT_SET('M', &sms, "Simultaneous Multi-Slice reconstruction"), OPT_SET('U', &nuconf.lowmem, "Use low-mem mode of the nuFFT"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (NULL != image_truth_file) im_truth = true; if (NULL != image_start_file) warm_start = true; if (0 <= bpsense_eps) conf.bpsense = true; admm.dynamic_tau = admm.relative_norm; if (conf.bpsense) nuconf.toeplitz = false; long max_dims[DIMS]; long map_dims[DIMS]; long pat_dims[DIMS]; long img_dims[DIMS]; long coilim_dims[DIMS]; long ksp_dims[DIMS]; long traj_dims[DIMS]; // load kspace and maps and get dimensions complex float* kspace = load_cfl(argv[1], DIMS, ksp_dims); if (sms) { debug_printf(DP_INFO, "SMS reconstruction: MB = %ld\n", ksp_dims[SLICE_DIM]); } complex float* maps = load_cfl(argv[2], DIMS, map_dims); unsigned int map_flags = md_nontriv_dims(DIMS, map_dims); map_flags |= FFT_FLAGS | SENS_FLAGS; long basis_dims[DIMS]; complex float* basis = NULL; if (NULL != basis_file) { basis = load_cfl(basis_file, DIMS, basis_dims); assert(!md_check_dimensions(DIMS, basis_dims, COEFF_FLAG | TE_FLAG)); } complex float* traj = NULL; if (NULL != traj_file) traj = load_cfl(traj_file, DIMS, traj_dims); md_copy_dims(DIMS, max_dims, ksp_dims); md_copy_dims(5, max_dims, map_dims); assert(1 == ksp_dims[COEFF_DIM]); long bmx_dims[DIMS]; if (NULL != basis_file) { assert(basis_dims[TE_DIM] == ksp_dims[TE_DIM]); max_dims[COEFF_DIM] = basis_dims[COEFF_DIM]; md_copy_dims(DIMS, bmx_dims, max_dims); debug_printf(DP_INFO, "Basis: "); debug_print_dims(DP_INFO, DIMS, bmx_dims); max_dims[TE_DIM] = 1; debug_printf(DP_INFO, "Max: "); debug_print_dims(DP_INFO, DIMS, max_dims); // if (NULL != traj_file) // nuconf.toeplitz = false; } md_select_dims(DIMS, ~COIL_FLAG, img_dims, max_dims); md_select_dims(DIMS, ~MAPS_FLAG, coilim_dims, max_dims); if (!md_check_compat(DIMS, ~(MD_BIT(MAPS_DIM)|FFT_FLAGS), img_dims, map_dims)) error("Dimensions of image and sensitivities do not match!\n"); if ((NULL != traj_file) && (!md_check_compat(DIMS, ~0, ksp_dims, traj_dims))) error("Dimensions of data and trajectory do not match!\n"); assert(1 == ksp_dims[MAPS_DIM]); if (conf.gpu) num_init_gpu_device(gpun); else num_init(); // print options if (conf.gpu) debug_printf(DP_INFO, "GPU reconstruction\n"); if (map_dims[MAPS_DIM] > 1) debug_printf(DP_INFO, "%ld maps.\nESPIRiT reconstruction.\n", map_dims[MAPS_DIM]); if (conf.bpsense) debug_printf(DP_INFO, "Basis Pursuit formulation\n"); if (hogwild) debug_printf(DP_INFO, "Hogwild stepsize\n"); if (admm.dynamic_rho) debug_printf(DP_INFO, "ADMM Dynamic stepsize\n"); if (admm.relative_norm) debug_printf(DP_INFO, "ADMM residual balancing\n"); if (im_truth) debug_printf(DP_INFO, "Compare to truth\n"); if (randshift) shift_mode = 1; if (overlapping_blocks) { if (randshift) debug_printf(DP_WARN, "Turning off random shifts\n"); shift_mode = 2; debug_printf(DP_INFO, "Fully overlapping LLR blocks\n"); } assert(!((conf.rwiter > 1) && (nuconf.toeplitz || conf.bpsense))); // initialize sampling pattern complex float* pattern = NULL; if (NULL != pat_file) { pattern = load_cfl(pat_file, DIMS, pat_dims); assert(md_check_compat(DIMS, COIL_FLAG, ksp_dims, pat_dims)); } else { md_select_dims(DIMS, ~COIL_FLAG, pat_dims, ksp_dims); pattern = md_alloc(DIMS, pat_dims, CFL_SIZE); estimate_pattern(DIMS, ksp_dims, COIL_FLAG, pattern, kspace); } if (NULL != traj_file) { if (NULL == pat_file && NULL == basis) { md_free(pattern); pattern = NULL; } else { long ksp_strs[DIMS]; md_calc_strides(DIMS, ksp_strs, ksp_dims, CFL_SIZE); long pat_strs[DIMS]; md_calc_strides(DIMS, pat_strs, pat_dims, CFL_SIZE); md_zmul2(DIMS, ksp_dims, ksp_strs, kspace, ksp_strs, kspace, pat_strs, pattern); } } else { // print some statistics long T = md_calc_size(DIMS, pat_dims); long samples = (long)pow(md_znorm(DIMS, pat_dims, pattern), 2.); debug_printf(DP_INFO, "Size: %ld Samples: %ld Acc: %.2f\n", T, samples, (float)T / (float)samples); } if (NULL == traj_file) { fftmod(DIMS, ksp_dims, FFT_FLAGS, kspace, kspace); fftmod(DIMS, map_dims, FFT_FLAGS, maps, maps); } // apply fov mask to sensitivities if (-1. != restrict_fov) { float restrict_dims[DIMS] = { [0 ... DIMS - 1] = 1. }; restrict_dims[0] = restrict_fov; restrict_dims[1] = restrict_fov; restrict_dims[2] = restrict_fov; apply_mask(DIMS, map_dims, maps, restrict_dims); } // initialize forward_op and precond_op const struct linop_s* forward_op = NULL; const struct operator_s* precond_op = NULL; if (NULL == traj_file) { forward_op = sense_init(max_dims, map_flags, maps); // apply temporal basis if (NULL != basis_file) { const struct linop_s* basis_op = linop_fmac_create(DIMS, bmx_dims, COEFF_FLAG, TE_FLAG, ~(COEFF_FLAG | TE_FLAG), basis); forward_op = linop_chain_FF(forward_op, basis_op); } } else { forward_op = sense_nc_init(max_dims, map_dims, maps, ksp_dims, traj_dims, traj, nuconf, pat_dims, pattern, basis_dims, basis, (struct operator_s**)&precond_op, sms); } // apply scaling if (0. == scaling) { if (NULL == traj_file) { scaling = estimate_scaling(ksp_dims, NULL, kspace); } else { complex float* adj = md_alloc(DIMS, img_dims, CFL_SIZE); linop_adjoint(forward_op, DIMS, img_dims, adj, DIMS, ksp_dims, kspace); scaling = estimate_scaling_norm(1., md_calc_size(DIMS, img_dims), adj, false); md_free(adj); } } if (0. == scaling ) { debug_printf(DP_WARN, "Estimated scale is zero. Set to one."); scaling = 1.; } else { debug_printf(DP_DEBUG1, "Inverse scaling of the data: %f\n", scaling); md_zsmul(DIMS, ksp_dims, kspace, kspace, 1. / scaling); if (conf.bpsense) { bpsense_eps /= scaling; debug_printf(DP_DEBUG1, "scaling basis pursuit eps: %.3e\n", bpsense_eps); } } complex float* image = create_cfl(argv[3], DIMS, img_dims); md_clear(DIMS, img_dims, image, CFL_SIZE); long img_truth_dims[DIMS]; complex float* image_truth = NULL; if (im_truth) { image_truth = load_cfl(image_truth_file, DIMS, img_truth_dims); //md_zsmul(DIMS, img_dims, image_truth, image_truth, 1. / scaling); #ifdef USE_CUDA if (conf.gpu) { complex float* gpu_image_truth = md_gpu_move(DIMS, img_dims, image_truth, CFL_SIZE); unmap_cfl(DIMS, img_dims, image_truth); image_truth = gpu_image_truth; } #endif xfree(image_truth_file); } long img_start_dims[DIMS]; complex float* image_start = NULL; if (warm_start) { debug_printf(DP_DEBUG1, "Warm start: %s\n", image_start_file); image_start = load_cfl(image_start_file, DIMS, img_start_dims); assert(md_check_compat(DIMS, 0u, img_start_dims, img_dims)); xfree(image_start_file); // if rescaling at the end, assume the input has also been rescaled if (scale_im && (scaling != 0.)) md_zsmul(DIMS, img_dims, image_start, image_start, 1. / scaling); } assert((0u == loop_flags) || (NULL == image_truth)); assert((0u == loop_flags) || (NULL == image_start)); assert((0u == loop_flags) || (NULL == traj_file)); assert(!(loop_flags & COIL_FLAG)); const complex float* image_start1 = image_start; long loop_dims[DIMS]; md_select_dims(DIMS, loop_flags, loop_dims, max_dims); long img1_dims[DIMS]; md_select_dims(DIMS, ~loop_flags, img1_dims, img_dims); long ksp1_dims[DIMS]; md_select_dims(DIMS, ~loop_flags, ksp1_dims, ksp_dims); long max1_dims[DIMS]; md_select_dims(DIMS, ~loop_flags, max1_dims, max_dims); long pat1_dims[DIMS]; md_select_dims(DIMS, ~loop_flags, pat1_dims, pat_dims); complex float* pattern1 = NULL; if (NULL != pattern) { pattern1 = md_alloc(DIMS, pat1_dims, CFL_SIZE); md_slice(DIMS, loop_flags, (const long[DIMS]){ [0 ... DIMS - 1] = 0 }, pat_dims, pattern1, pattern, CFL_SIZE); } // FIXME: re-initialize forward_op and precond_op if ((NULL == traj_file) && (0u != loop_flags) && !sms) { // FIXME: no basis linop_free(forward_op); forward_op = sense_init(max1_dims, map_flags, maps); // basis pursuit requires the full forward model to add as a linop constraint if (conf.bpsense) { const struct linop_s* sample_op = linop_sampling_create(max1_dims, pat1_dims, pattern1); struct linop_s* tmp = linop_chain(forward_op, sample_op); linop_free(sample_op); linop_free(forward_op); forward_op = tmp; } } double maxeigen = 1.; if (eigen) { maxeigen = estimate_maxeigenval(forward_op->normal); debug_printf(DP_INFO, "Maximum eigenvalue: %.2e\n", maxeigen); } // initialize prox functions const struct operator_p_s* thresh_ops[NUM_REGS] = { NULL }; const struct linop_s* trafos[NUM_REGS] = { NULL }; opt_reg_configure(DIMS, img1_dims, &ropts, thresh_ops, trafos, llr_blk, shift_mode, conf.gpu); if (conf.bpsense) opt_bpursuit_configure(&ropts, thresh_ops, trafos, forward_op, kspace, bpsense_eps); int nr_penalties = ropts.r; struct reg_s* regs = ropts.regs; // choose algorithm if (ALGO_DEFAULT == algo) algo = italgo_choose(nr_penalties, regs); if (conf.bpsense) assert((ALGO_ADMM == algo) || (ALGO_PRIDU == algo)); // choose step size if ((ALGO_IST == algo) || (ALGO_FISTA == algo) || (ALGO_PRIDU == algo)) { // For non-Cartesian trajectories, the default // will usually not work. TODO: The same is true // for sensitivities which are not normalized, but // we do not detect this case. if ((NULL != traj_file) && (-1. == step) && !eigen) debug_printf(DP_WARN, "No step size specified.\n"); if (-1. == step) step = 0.95; } if ((ALGO_CG == algo) || (ALGO_ADMM == algo)) if (-1. != step) debug_printf(DP_INFO, "Stepsize ignored.\n"); step /= maxeigen; // initialize algorithm struct iter it = italgo_config(algo, nr_penalties, regs, maxiter, step, hogwild, fast, admm, scaling, warm_start); if (ALGO_CG == algo) nr_penalties = 0; bool trafos_cond = ( (ALGO_PRIDU == algo) || (ALGO_ADMM == algo) || ( (ALGO_NIHT == algo) && (regs[0].xform == NIHTWAV))); // FIXME: will fail with looped dims struct iter_monitor_s* monitor = NULL; if (im_truth) monitor = create_monitor(2*md_calc_size(DIMS, img_dims), (const float*)image_truth, NULL, NULL); const struct operator_p_s* po = sense_recon_create(&conf, max1_dims, forward_op, pat1_dims, ((NULL != traj_file) || conf.bpsense) ? NULL : pattern1, it.italgo, it.iconf, image_start1, nr_penalties, thresh_ops, trafos_cond ? trafos : NULL, precond_op, monitor); const struct operator_s* op = operator_p_bind(po, 1.); // operator_p_free(po); // FIXME long strsx[2][DIMS]; const long* strs[2] = { strsx[0], strsx[1] }; md_calc_strides(DIMS, strsx[0], img_dims, CFL_SIZE); md_calc_strides(DIMS, strsx[1], ksp_dims, CFL_SIZE); for (unsigned int i = 0; i < DIMS; i++) { if (MD_IS_SET(loop_flags, i)) { strsx[0][i] = 0; strsx[1][i] = 0; } } if (0 != loop_flags) { op = operator_copy_wrapper(2, strs, op); // op = operator_loop(DIMS, loop_dims, op); op = operator_loop_parallel(DIMS, loop_dims, op, loop_flags, conf.gpu); } operator_apply(op, DIMS, img_dims, image, DIMS, conf.bpsense ? img_dims : ksp_dims, conf.bpsense ? NULL : kspace); operator_free(op); opt_reg_free(&ropts, thresh_ops, trafos); italgo_config_free(it); if (scale_im) md_zsmul(DIMS, img_dims, image, image, scaling); // clean up if (NULL != pat_file) unmap_cfl(DIMS, pat_dims, pattern); else md_free(pattern); if (NULL != pattern1) md_free(pattern1); unmap_cfl(DIMS, map_dims, maps); unmap_cfl(DIMS, ksp_dims, kspace); unmap_cfl(DIMS, img_dims, image); if (NULL != traj) unmap_cfl(DIMS, traj_dims, traj); if (im_truth) { #ifdef USE_CUDA if (conf.gpu) md_free(image_truth); else #endif unmap_cfl(DIMS, img_dims, image_truth); } if (image_start) unmap_cfl(DIMS, img_dims, image_start); xfree(pat_file); xfree(traj_file); xfree(basis_file); double end_time = timestamp(); debug_printf(DP_INFO, "Total Time: %f\n", end_time - start_time); return 0; } bart-0.5.00/src/pocsense.c000066400000000000000000000116141353046746100153120ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * 2014 Jonathan Tamir */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "num/ops.h" #include "num/ops_p.h" #include "num/iovec.h" #include "linops/someops.h" #include "linops/linop.h" #include "linops/waveop.h" #include "iter/iter.h" #include "iter/prox.h" #include "iter/thresh.h" #include "sense/pocs.h" #include "sense/optcom.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" static const char usage_str[] = " "; static const char help_str[] = "Perform POCSENSE reconstruction."; int main_pocsense(int argc, char* argv[]) { float alpha = 0.; int maxiter = 50; bool l1wav = false; float lambda = -1.; bool use_gpu = false; bool use_admm = false; float admm_rho = -1.; int l1type = 2; const struct opt_s opts[] = { OPT_INT('i', &maxiter, "iter", "max. number of iterations"), OPT_FLOAT('r', &alpha, "alpha", "regularization parameter"), OPT_INT('l', &l1type, "1/-l2", "toggle l1-wavelet or l2 regularization"), OPT_SET('g', &use_gpu, "()"), OPT_FLOAT('o', &lambda, "", "()"), OPT_FLOAT('m', &admm_rho, "", "()"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (1 == l1type) l1wav = true; else if (2 == l1type) l1wav = false; else error("Unknown regularization type."); unsigned int N = DIMS; long dims[N]; long ksp_dims[N]; complex float* kspace_data = load_cfl(argv[1], N, ksp_dims); complex float* sens_maps = load_cfl(argv[2], N, dims); for (int i = 0; i < 4; i++) // sizes2[4] may be > 1 if (ksp_dims[i] != dims[i]) error("Dimensions of kspace and sensitivities do not match!\n"); assert(1 == ksp_dims[MAPS_DIM]); num_init(); long dims1[N]; md_select_dims(N, ~(COIL_FLAG|MAPS_FLAG), dims1, dims); // ----------------------------------------------------------- // memory allocation complex float* result = create_cfl(argv[3], N, ksp_dims); complex float* pattern = md_alloc(N, dims1, CFL_SIZE); // ----------------------------------------------------------- // pre-process data float scaling = estimate_scaling(ksp_dims, NULL, kspace_data); md_zsmul(N, ksp_dims, kspace_data, kspace_data, 1. / scaling); estimate_pattern(N, ksp_dims, COIL_FLAG, pattern, kspace_data); // ----------------------------------------------------------- // l1-norm threshold operator const struct operator_p_s* thresh_op = NULL; const struct linop_s* wave_op = NULL; if (l1wav) { long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(ksp_dims[0], 16); minsize[1] = MIN(ksp_dims[1], 16); minsize[2] = MIN(ksp_dims[2], 16); long strs[DIMS]; md_calc_strides(DIMS, strs, ksp_dims, CFL_SIZE); wave_op = linop_wavelet_create(DIMS, FFT_FLAGS, ksp_dims, strs, minsize, false); thresh_op = prox_unithresh_create(DIMS, wave_op, alpha, COIL_FLAG); } #if 0 else { thresh_op = prox_leastsquares_create(DIMS, ksp_dims, alpha, NULL); } #endif // ----------------------------------------------------------- // italgo interface italgo_fun2_t italgo = NULL; iter_conf* iconf = NULL; struct iter_pocs_conf pconf = iter_pocs_defaults; pconf.maxiter = maxiter; struct iter_admm_conf mmconf = iter_admm_defaults; mmconf.maxiter = maxiter; mmconf.rho = admm_rho; struct linop_s* eye = linop_identity_create(DIMS, ksp_dims); struct linop_s* ops[3] = { eye, eye, eye }; struct linop_s** ops2 = NULL; if (use_admm) { italgo = iter2_admm; iconf = CAST_UP(&mmconf); ops2 = ops; } else { italgo = iter2_pocs; iconf = CAST_UP(&pconf); } // ----------------------------------------------------------- // pocsense recon debug_printf(DP_INFO, "Reconstruction...\n"); fftmod(N, ksp_dims, FFT_FLAGS, kspace_data, kspace_data); if (use_gpu) #ifdef USE_CUDA pocs_recon_gpu2(italgo, iconf, (const struct linop_s**)ops2, dims, thresh_op, alpha, lambda, result, sens_maps, pattern, kspace_data); #else assert(0); #endif else pocs_recon2(italgo, iconf, (const struct linop_s**)ops2, dims, thresh_op, alpha, lambda, result, sens_maps, pattern, kspace_data); ifftmod(N, ksp_dims, FFT_FLAGS, result, result); debug_printf(DP_INFO, "Done.\n"); md_zsmul(N, ksp_dims, result, result, scaling); linop_free(eye); md_free(pattern); if (NULL != thresh_op) operator_p_free(thresh_op); if (NULL != wave_op) linop_free(wave_op); unmap_cfl(N, ksp_dims, result); unmap_cfl(N, ksp_dims, kspace_data); unmap_cfl(N, dims, sens_maps); return 0; } bart-0.5.00/src/poisson.c000066400000000000000000000137331353046746100151710ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2013, 2015 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "num/init.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/pd.h" #include "misc/opts.h" static void random_point(int D, float p[static D]) { for (int i = 0; i < D; i++) p[i] = uniform_rand(); } static float dist(int D, const float a[static D], const float b[static D]) { float r = 0.; for (int i = 0; i < D; i++) r += powf(a[i] - b[i], 2.); return sqrtf(r); } static float maxn(int D, const float a[static D], const float b[static D]) { float r = 0.; for (int i = 0; i < D; i++) r = MAX(fabsf(a[i] - b[i]), r); return r; } static const char usage_str[] = ""; static const char help_str[] = "Computes Poisson-disc sampling pattern."; int main_poisson(int argc, char* argv[]) { int yy = 128; int zz = 128; bool cutcorners = false; float vardensity = 0.; bool vd_def = false; int T = 1; int rnd = 0; int randseed = 11235; bool msk = true; int points = -1; float mindist = 1. / 1.275; float yscale = 1.; float zscale = 1.; unsigned int calreg = 0; const struct opt_s opts[] = { OPT_INT('Y', &yy, "size", "size dimension 1"), OPT_INT('Z', &zz, "size", "size dimension 2"), OPT_FLOAT('y', &yscale, "acc", "acceleration dim 1"), OPT_FLOAT('z', &zscale, "acc", "acceleration dim 2"), OPT_UINT('C', &calreg, "size", "size of calibration region"), OPT_SET('v', &vd_def, "variable density"), OPT_FLOAT('V', &vardensity, "", "(variable density)"), OPT_SET('e', &cutcorners, "elliptical scanning"), OPT_FLOAT('D', &mindist, "", "()"), OPT_INT('T', &T, "", "()"), OPT_CLEAR('m', &msk, "()"), OPT_INT('R', &points, "", "()"), OPT_INT('s', &randseed, "seed", "random seed"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); num_rand_init(randseed); if (vd_def && (0. == vardensity)) vardensity = 20.; if (-1 != points) rnd = 1; assert((yscale >= 1.) && (zscale >= 1.)); // compute mindest and scaling float kspext = MAX(yy, zz); int Pest = T * (int)(1.2 * powf(kspext, 2.) / (yscale * zscale)); mindist /= kspext; yscale *= (float)kspext / (float)yy; zscale *= (float)kspext / (float)zz; if (vardensity != 0.) { // TODO } long dims[5] = { 1, yy, zz, T, 1 }; complex float (*mask)[T][zz][yy] = NULL; if (msk) { mask = MD_CAST_ARRAY3_PTR(complex float, 5, dims, create_cfl(argv[1], 5, dims), 1, 2, 3); md_clear(5, dims, &(*mask)[0][0][0], sizeof(complex float)); } int M = rnd ? (points + 1) : Pest; int P; while (true) { PTR_ALLOC(float[M][2], points); PTR_ALLOC(int[M], kind); // int (*kind)[M] = TYPE_ALLOC(int[M]); (*kind)[0] = 0; if (!rnd) { (*points)[0][0] = 0.5; (*points)[0][1] = 0.5; if (1 == T) { P = poissondisc(2, M, 1, vardensity, mindist, *points); } else { float (*delta)[T][T] = TYPE_ALLOC(float[T][T]); float dd[T]; for (int i = 0; i < T; i++) dd[i] = mindist; mc_poisson_rmatrix(2, T, *delta, dd); P = poissondisc_mc(2, T, M, 1, vardensity, *delta, *points, *kind); XFREE(delta); } } else { // random pattern P = M - 1; for (int i = 0; i < P; i++) random_point(2, (*points)[i]); } if (P < M) { for (int i = 0; i < P; i++) { (*points)[i][0] = ((*points)[i][0] - 0.5) * yscale + 0.5; (*points)[i][1] = ((*points)[i][1] - 0.5) * zscale + 0.5; } // throw away points outside float center[2] = { 0.5, 0.5 }; int j = 0; for (int i = 0; i < P; i++) { if ((cutcorners ? dist : maxn)(2, center, (*points)[i]) <= 0.5) { (*points)[j][0] = (*points)[i][0]; (*points)[j][1] = (*points)[i][1]; j++; } } P = j; if (msk) { // rethink module here for (int i = 0; i < P; i++) { int yy = (int)floorf((*points)[i][0] * dims[1]); int zz = (int)floorf((*points)[i][1] * dims[2]); if ((yy < 0) || (yy >= dims[1]) || (zz < 0) || (zz >= dims[2])) continue; if (1 == T) (*mask)[0][zz][yy] = 1.;//cexpf(2.i * M_PI * (float)(*kind)[i] / (float)T); else (*mask)[(*kind)[i]][zz][yy] = 1.;//cexpf(2.i * M_PI * (float)(*kind)[i] / (float)T); } } else { #if 1 long sdims[2] = { 3, P }; //complex float (*samples)[P][3] = (void*)create_cfl(argv[1], 2, sdims); complex float (*samples)[P][3] = MD_CAST_ARRAY2_PTR(complex float, 2, sdims, create_cfl(argv[1], 2, sdims), 0, 1); for (int i = 0; i < P; i++) { (*samples)[i][0] = 0.; (*samples)[i][1] = ((*points)[i][0] - 0.5) * dims[1]; (*samples)[i][2] = ((*points)[i][1] - 0.5) * dims[2]; // printf("%f %f\n", creal(samples[3 * i + 0]), creal(samples[3 * i + 1])); } unmap_cfl(2, sdims, &(*samples)[0][0]); #endif } PTR_FREE(points); PTR_FREE(kind); break; } // repeat with more points M *= 2; PTR_FREE(points); PTR_FREE(kind); } // calibration region assert((mask != NULL) || (0 == calreg)); assert((calreg <= dims[1]) && (calreg <= dims[2])); for (unsigned int i = 0; i < calreg; i++) { for (unsigned int j = 0; j < calreg; j++) { int y = (dims[1] - calreg) / 2 + i; int z = (dims[2] - calreg) / 2 + j; for (int k = 0; k < T; k++) { if (0. == (*mask)[k][z][y]) { (*mask)[k][z][y] = 1.; P++; } } } } printf("points: %d", P); if (1 != T) printf(", classes: %d", T); if (NULL != mask) { float f = cutcorners ? (M_PI / 4.) : 1.; printf(", grid size: %ldx%ld%s = %ld (R = %f)", dims[1], dims[2], cutcorners ? "x(pi/4)" : "", (long)(f * dims[1] * dims[2]), f * T * dims[1] * dims[2] / (float)P); unmap_cfl(5, dims, &(*mask)[0][0][0]); } printf("\n"); return 0; } bart-0.5.00/src/poly.c000066400000000000000000000025301353046746100144530ustar00rootroot00000000000000/* Copyright 2018. Massachusetts Institute of Technology. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Siddharth Iyer */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "L N a_0 a_1 ... a_N output"; static const char help_str[] = "Evaluate polynomial p(x) = a_0 + a_1 x + a_2 x^2 ... a_N x^N at x = {0, 1, ... , L - 1} where a_i are floats."; int main_poly(int argc, char* argv[]) { mini_cmdline(&argc, argv, -3, usage_str, help_str); num_init(); int L = atoi(argv[1]); int N = atoi(argv[2]); assert(L >= 1); assert(L <= 256 * 256); assert(N >= 0); assert(N + 1 <= L); assert(argc == 5 + N); long p_dims[] = { [0 ... DIMS - 1] = 1 }; p_dims[0] = L; complex float* p = create_cfl(argv[argc - 1], DIMS, p_dims); md_clear(DIMS, p_dims, p, CFL_SIZE); for (int x = 0; x < L; x++) { p[x] = (complex float) atof(argv[3]); for (int n = 1; n < N + 1; n++) { p[x] += ((complex float) atof(argv[3 + n])) * cpowf(x, n); } } unmap_cfl(N, p_dims, p); return 0; } bart-0.5.00/src/python/000077500000000000000000000000001353046746100146455ustar00rootroot00000000000000bart-0.5.00/src/python/pyBART.cpp.in000066400000000000000000000307371353046746100170710ustar00rootroot00000000000000/* Copyright 2018. Damien Nguyen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Damien Nguyen */ #include #define PY_ARRAY_UNIQUE_SYMBOL bart_numpy_identifier #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include "pybind11/pybind11.h" #include "pybind11/operators.h" #include "pybind11/stl.h" #include "pybind11/numpy.h" #include "python/pyBART_pybind11_patch.h" namespace py = pybind11; using numpy_farray_t = py::array_t, py::array::f_style | py::array::forcecast>; using numpy_array_t = py::array_t, py::array::c_style | py::array::forcecast>; #include #include #include #define _Bool bool #include "bart_embed_api.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/mmiocc.hh" #ifndef DIMS # define DIMS 16 #endif #define DP_UNSET -1 /* ========================================================================== */ struct error_jumper_s { bool initialized; jmp_buf buf; }; extern "C" struct error_jumper_s error_jumper; /* -------------------------------------------------------------------------- */ struct disk_cfl_data_s { long D; long dims[DIMS]; const std::complex* data; }; struct unmap_cfl_deleter { void operator() (disk_cfl_data_s* p) const { unmap_cfl(p->D, p->dims, (_Complex float*) p->data); p->data = nullptr; } }; using disk_cfl_ptr = std::unique_ptr; static std::vector disk_cfl_data; static std::vector> load_cfl_base_objects; /* ========================================================================== */ extern "C" { extern const char* bart_version; int bart_command(int size, char* out, int argc, char* argv[]); } bool register_mem_cfl_python(const char* name, const numpy_farray_t& array); void disk_cfl_cleanup(void); /* Docstrings */ #include "python/pyBART_docstrings.c" /* Available functions */ static py::object call_bart(const char* cmdline); static void cleanup_memory(); static numpy_farray_t load_cfl_python(const std::string& name); static void register_python_memory(const std::string& name, numpy_array_t& array); static void register_python_memory(const std::string& name, numpy_farray_t& array); static py::int_ get_debug_level(); static void set_debug_level(py::int_ param); static void set_debug_level(py::float_ param); static void set_debug_level(py::str param); @PYBART_FUNCTION_PROTOTYPE@ /* ========================================================================== */ #define ADD_PYTHON_CONSTANT(name) \ m.attr(#name) = int(name) #if PY_MAJOR_VERSION >= 3 static int pyBART_clear(PyObject*) { cleanup_memory(); return 0; } /* * This is the GC function for the module. * Ideally we could detect dirty memory items and delete them with this * function. * However, for that to work, we need a way to detect when all NumPy arrays * pointing to one memory location are destroyed so that we know we can safely * do so without incurring any segmentation faults... */ static int pyBART_traverse(PyObject* m, visitproc visit, void* arg) { return 0; } #endif /* PY_MAJOR_VERSION >= 3 */ MYPYBIND11_MODULE(pyBART, m) { py::options options; options.disable_function_signatures(); m.def("bart", call_bart, call_bart_docstring); m.def("cleanup_memory", cleanup_memory, cleanup_memory_docstring); m.def("load_cfl", load_cfl_python, load_cfl_python_docstring, py::return_value_policy::reference); m.def("register_memory", py::overload_cast(register_python_memory), register_python_memory_docstring); m.def("register_memory", py::overload_cast(register_python_memory), register_python_memory_docstring); m.def("get_debug_level", get_debug_level, get_debug_level_docstring); m.def("set_debug_level", py::overload_cast(set_debug_level), set_debug_level_int_docstring); m.def("set_debug_level", py::overload_cast(set_debug_level), set_debug_level_float_docstring); m.def("set_debug_level", py::overload_cast(set_debug_level), set_debug_level_str_docstring); @PYBART_COMMANDS_MODULE_METHODS@ ADD_PYTHON_CONSTANT(DP_ERROR); ADD_PYTHON_CONSTANT(DP_WARN); ADD_PYTHON_CONSTANT(DP_INFO); ADD_PYTHON_CONSTANT(DP_DEBUG1); ADD_PYTHON_CONSTANT(DP_DEBUG2); ADD_PYTHON_CONSTANT(DP_DEBUG3); ADD_PYTHON_CONSTANT(DP_DEBUG4); ADD_PYTHON_CONSTANT(DP_TRACE); ADD_PYTHON_CONSTANT(DP_ALL); ADD_PYTHON_CONSTANT(DP_UNSET); MYPYBIND11_MODULE_DESTRUCTOR_IMPLEMENT; m.attr("__doc__") = pyBART_module_doc; m.attr("__version__") = bart_version; /* Load `numpy` functionality. */ if (_import_array() < 0) { PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); throw py::error_already_set(); } } #undef ADD_PYTHON_CONSTANT /* ========================================================================== */ py::object call_submain(const char* subcommand, const char* cmdline_in) { enum { MAX_ARGS = 256 }; char cmdline[1024] = { '\0' }; char output[512] = { '\0' }; snprintf(cmdline, 1024, "%s %s", subcommand, cmdline_in); // tokenize the command string into argc/argv (basic, hopefully enough) int argc = 0; char *argv[MAX_ARGS]; char *argvv[MAX_ARGS]; char *p2 = strtok(cmdline, " "); while (p2 && argc < MAX_ARGS-1) { argv[argc++] = p2; p2 = strtok(0, " "); } argv[argc] = 0; int ret = bart_command(512, output, argc, argv); // execute bart if (strlen(output) > 0) { return py::str(output); } else { if (PyErr_Occurred()) { throw std::runtime_error("something wrong happened"); return py::none(); } else { return py::int_(ret); } } } /* ========================================================================== */ py::object call_bart(const char* cmdline) { return call_submain("", cmdline); } /* ========================================================================== */ void register_python_memory(const std::string& name, numpy_farray_t& array) { debug_printf(DP_DEBUG4, "in: register_python_memory (F-contiguous)\n"); /* * No need to use the error_jumper here since this code path will * never encounter a call to BART's error() function * * However, this call might throw, which would then be handled by pybind11 */ register_mem_cfl_python(name.c_str(), array); } void register_python_memory(const std::string& name, numpy_array_t& array) { debug_printf(DP_DEBUG4, "in: register_python_memory (C-contiguous)\n"); debug_printf(DP_WARN, "BART only works with F-contiguous arrays (column major).\n" "The array being registered is C-contiguous (row major)!\n" "A copy of the data will be stored internally with the " "appropriate ordering.\n"); register_mem_cfl_python(name.c_str(), array); } /* ========================================================================== */ static void register_disk_cfl(unsigned int D, const long dims[__VLA(D)], void* data) { auto new_data = disk_cfl_ptr(new disk_cfl_data_s); new_data->D = D; memcpy(new_data->dims, dims, D * sizeof(long)); new_data->data = reinterpret_cast*>(data); disk_cfl_data.push_back(std::move(new_data)); } void disk_cfl_cleanup(void) { disk_cfl_data.clear(); } /* -------------------------------------------------------------------------- */ numpy_farray_t load_cfl_python(const std::string& name) { debug_printf(DP_DEBUG4, "in: load_cfl_python\n"); error_jumper.initialized = 1; if (setjmp(error_jumper.buf) == 0) { long dims[DIMS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void* data = load_cfl(name.c_str(), DIMS, dims); if (data == nullptr) { throw std::runtime_error("failed loading CFL file"); } if (!is_mem_cfl(reinterpret_cast<_Complex float*>(data))) { debug_printf(DP_DEBUG4, " registering on-disk CFL file\n"); register_disk_cfl(DIMS, dims, data); } std::vector pydims(dims, dims+DIMS); /* * Make sure that all NumPy arrays pointing to the same memory * location have the same base object. * This also tells NumPy that the arrays are not the owners * of the memory they refer to. * * The destructor is a bit dumb since it's not doing anything * but could be used for tracing */ auto it = std::find_if(load_cfl_base_objects.begin(), load_cfl_base_objects.end(), [&] (auto& t) { return std::get<0>(t) == data; }); if (it == load_cfl_base_objects.end()) { debug_printf(DP_DEBUG4, " creating new Python capsule as base " "object\n"); auto tmp = std::make_tuple(data, py::capsule(data, [](void *v) {})); load_cfl_base_objects.push_back(std::move(tmp)); it = std::prev(load_cfl_base_objects.end()); } else { debug_printf(DP_DEBUG4, " re-using existing Python capsule as base " "object\n"); } debug_printf(DP_DEBUG4, " creating NumPy.ndarray with capsule " "as base\n"); auto ret = numpy_farray_t(pydims, reinterpret_cast*>(data), std::get<1>(*it)); using api = py::detail::npy_api; py::detail::array_proxy(ret.ptr())->flags &= ~api::NPY_ARRAY_WRITEABLE_; return ret; } else { throw py::error_already_set(); } } /* ========================================================================== */ void cleanup_memory() { deallocate_all_mem_cfl(); disk_cfl_cleanup(); load_cfl_base_objects.clear(); } /* ========================================================================== */ #define IF_LEVEL_IS(name) \ if (debug_level == name) { \ constant = module_dict[#name]; \ } py::int_ get_debug_level() { auto module_dict = py::reinterpret_borrow(py::module::import("pyBART").attr("__dict__")); py::int_ constant; IF_LEVEL_IS(DP_ERROR) else IF_LEVEL_IS(DP_INFO) else IF_LEVEL_IS(DP_DEBUG1) else IF_LEVEL_IS(DP_DEBUG2) else IF_LEVEL_IS(DP_DEBUG3) else IF_LEVEL_IS(DP_DEBUG4) else IF_LEVEL_IS(DP_TRACE) else IF_LEVEL_IS(DP_ALL) else { constant = module_dict["DP_UNSET"]; } return constant; } #undef IF_LEVEL_IS /* -------------------------------------------------------------------------- */ void set_debug_level_impl(int level) { #define ADD_CASE(name) case name: debug_level = name; break switch (level) { ADD_CASE(DP_ERROR); ADD_CASE(DP_WARN); ADD_CASE(DP_INFO); ADD_CASE(DP_DEBUG1); ADD_CASE(DP_DEBUG2); ADD_CASE(DP_DEBUG3); ADD_CASE(DP_DEBUG4); ADD_CASE(DP_TRACE); ADD_CASE(DP_ALL); ADD_CASE(DP_UNSET); default: printf("WARNING: invalid value for debug level (%d)," " setting level to DP_UNSET (%d)\n", level, DP_UNSET); debug_level = DP_UNSET; } #undef ADD_CASE } void set_debug_level(py::int_ param) { set_debug_level_impl(param); } void set_debug_level(py::float_ param) { double d = param.cast(); int level = d; if (level != d) { throw std::runtime_error("Cannot have decimal debug level"); } else { set_debug_level_impl(level); } } void set_debug_level(py::str param) { int level(DP_UNSET); const std::string str(param); #define IF_STR_IS(name) if (str == #name) { level = name; } IF_STR_IS(DP_ERROR) else IF_STR_IS(DP_WARN) else IF_STR_IS(DP_INFO) else IF_STR_IS(DP_DEBUG1) else IF_STR_IS(DP_DEBUG2) else IF_STR_IS(DP_DEBUG3) else IF_STR_IS(DP_DEBUG4) else IF_STR_IS(DP_TRACE) else IF_STR_IS(DP_ALL) else IF_STR_IS(DP_UNSET) else { // TODO: add str to error message throw std::runtime_error("String is not a valid debug level"); } #undef IF_STR_IS set_debug_level_impl(level); } /* ========================================================================== */ @PYBART_COMMANDS_IMPLEMENTATION@ bart-0.5.00/src/python/pyBART_docstrings.c000066400000000000000000000157751353046746100203700ustar00rootroot00000000000000 #if PY_MAJOR_VERSION >= 3 #define add_doc(name, string) PyDoc_STRVAR(name, string) #else #define add_doc(name, string) static const char name[] = string; #endif /* PY_MAJOR_VERSION >= 3 */ add_doc(pyBART_module_name, "pyBART"); add_doc(pyBART_module_doc, "pyBART\n" "======\n" "\n" "Provides easy access to BART's functionalities from within Python\n" "\n" "How to use the documentation\n" "----------------------------\n" "Documentation is available through docstrings provided with the\n" "code.\n" "\n" "Use the built-in ``help`` function to view a function's docstring::\n" "\n" " >>> help(pyBART.bart)\n" "\n" "The docstring examples assume that `numpy` has been imported as `np`::\n" "\n" " >>> import numpy as np\n" "\n" "Code snippets are indicated by three greater-than signs::\n" "\n" " >>> x = 42\n" " >>> x = x + 1\n" "\n" "Cleaning up in-memory data\n" "--------------------------\n" "After doing some processing using pyBART, some data may remain in\n" "'in-memory' CFL files and/or some memory may be mapped from\n" "locations on disk (from regular CFL files).\n" "In order to properly cleanup and free those memory locations, you\n" "need to call the cleanup_memory() function from pyBART::\n" "\n" " >>> pyBART.cleanup_memory()\n" "\n" "Useful constants\n" "----------------\n" "\n" "Constants related to debug levels:\n" " - DP_UNSET (-1)\n" " - DP_ERROR\n" " - DP_WARN\n" " - DP_INFO\n" " - DP_DEBUG1\n" " - DP_DEBUG2\n" " - DP_DEBUG3\n" " - DP_DEBUG4\n" " - DP_TRACE\n" " - DP_ALL\n"); add_doc(call_bart_docstring, "pyBART.bart(command_line) -> string or int\n" "--\n\n" "Execute a BART command\n" "\n" "Parameters\n" "----------\n" "command_line : str\n" " BART command line to execute\n" "\n" "Returns\n" "-------\n" "result : string or int\n" " Output of the command or return value of the BART main function\n" " The list of functions outputting strings is listed below:\n" " - bitmask\n" " - estdelay\n" " - estdims\n" " - estshift\n" " - estvar\n" " - nrmse\n" " - sdot\n" " - show\n" " - version\n" "\n" "All other commands will result in an int being returned.\n" "\n" "Examples\n" "--------\n" ">>> pyBART.bart('phantom -x 64 output')"); add_doc(bart_subcommand_docstring, "pyBART.(command_line) -> string or int\n" "--\n\n" "Execute the BART command\n" "This is effectively identical to calling pyBART.bart(' ...')\n" "\n" "See also help for pyBART.bart()"); add_doc(cleanup_memory_docstring, "pyBART.cleanup_memory()\n" "--\n\n" "Cleanup pyBART's internal memory database as well as close any \n" "remaining mapped memory locations (from CFL files on disk).\n" "\n" "Parameters\n" "----------\n" "None\n" "\n" "Note\n" "----\n" "After calling this function, all Python object pointing to any CFL\n" "files (in-memory or not) will be invalidated!\n"); add_doc(load_cfl_python_docstring, "pyBART.load_cfl(name) -> numpy.ndarray\n" "--\n\n" "Load some CFL file and return the data as an NumPy.ndarray.\n" "\n" "Parameters\n" "----------\n" "name : str\n" " Name of CFL file (see Note below)\n" "\n" "Returns\n" "-------\n" "out : numpy.ndarray\n" " Data contained in the CFL file\n" "\n" "\n" "Note\n" "----\n" "If pyBART is compiled with -DMEMONLY_CFL (CMake option: BART_MEMONLY_CFL)\n" "only in-memory CFL files can be read using this function.\n" "\n" "Raises\n" "------\n" "RuntimeError\n" " Raised if the file does not exist or an error occurs while reading it.\n" " \n" "Examples\n" "--------\n" ">>> a = np.array([ [0,1,2], [3,4,5] ])\n" ">>> pyBART.register_memory('test.mem', a.astype(np.complex64))\n" ">>> b = pyBART.load_cfl('test.mem')\n"); add_doc(register_python_memory_docstring, "pyBART.register_memory(name, data)\n" "--\n\n" "Register some NumPy data for later use with pyBART\n" "\n" "Parameters\n" "----------\n" "name : str\n" " Name of in-memory CFL file\n" "data : numpy.ndarray (with dtype=numpy.complex64)\n" " Data to transfer to pyBART\n" "\n" "Raises\n" "------\n" "TypeError\n" " Raised when:\n" " - `data` is not of type numpy.ndarray\n" " - `data` is not an array of complex floats (dtype = numpy.complex64)\n" " In that case, use a.asstype(numpy.complex64)\n" "\n" "RuntimeError\n" " Raised if `name` is empty or if getting the data from NumPy fails\n" "\n" "Examples\n" "--------\n" ">>> a = np.array([ [0,1,2], [3,4,5] ])\n" ">>> pyBART.register_memory('test.mem', a.astype(np.complex64))"); add_doc(get_debug_level_docstring, "pyBART.get_debug_level() -> int\n" "--\n\n" "Returns the current debug level\n" "\n" "Parameters\n" "----------\n" "None\n" "\n" "Returns\n" "-------\n" "result : int\n" " The value of result is one of:\n" " - pyBART.DP_UNSET\n" " - pyBART.DP_ERROR\n" " - pyBART.DP_WARN\n" " - pyBART.DP_INFO\n" " - pyBART.DP_DEBUG1\n" " - pyBART.DP_DEBUG2\n" " - pyBART.DP_DEBUG3\n" " - pyBART.DP_DEBUG4\n" " - pyBART.DP_TRACE\n" " - pyBART.DP_ALL\n" "\n" "Note\n" "----\n" "DP_UNSET is only returned if no value was previously set\n" "\n" "Examples\n" "--------\n" ">>> d = pyBART.get_debug_level()"); add_doc(set_debug_level_int_docstring, "pyBART.set_debug_level(level)\n" "--\n\n" "Sets the current debug level\n" "\n" "Parameters\n" "----------\n" "level : int or pyBART constant\n" " New value for the debug level\n" "\n" "Note\n" "----\n" "To reset the debug level, pass pyBART.DP_UNSET or -1 to this function\n" "\n" "List of available pyBART constants for the debug level:\n" " - pyBART.DP_UNSET\n" " - pyBART.DP_ERROR\n" " - pyBART.DP_WARN\n" " - pyBART.DP_INFO\n" " - pyBART.DP_DEBUG1\n" " - pyBART.DP_DEBUG2\n" " - pyBART.DP_DEBUG3\n" " - pyBART.DP_DEBUG4\n" " - pyBART.DP_TRACE\n" " - pyBART.DP_ALL\n" "\n" "Examples\n" "--------\n" ">>> pyBART.set_debug_level(2)\n" ">>> pyBART.set_debug_level(pyBART.DP_INFO)"); add_doc(set_debug_level_float_docstring, "pyBART.set_debug_level(level)\n" "--\n\n" "Sets the current debug level\n" "\n" "Parameters\n" "----------\n" "level : float\n" " New value for the debug level (must be a whole number)\n" "\n" "Note\n" "----\n" "To reset the debug level, pass -1 to this function\n" "\n" "Examples\n" "--------\n" ">>> pyBART.set_debug_level(-1.0)"); add_doc(set_debug_level_str_docstring, "pyBART.set_debug_level(level)\n" "--\n\n" "Sets the current debug level\n" "\n" "Parameters\n" "----------\n" "level : str\n" " New value for the debug level. Must be one of:\n" " - 'DP_UNSET'\n" " - 'DP_ERROR'\n" " - 'DP_WARN'\n" " - 'DP_INFO'\n" " - 'DP_DEBUG1'\n" " - 'DP_DEBUG2'\n" " - 'DP_DEBUG3'\n" " - 'DP_DEBUG4'\n" " - 'DP_TRACE'\n" " - 'DP_ALL'\n" "\n" "Note\n" "----\n" "To reset the debug level, pass pyBART.DP_UNSET or -1 to this function\n" "\n" "Examples\n" "--------\n" ">>> pyBART.set_debug_level('DP_INFO')"); bart-0.5.00/src/python/pyBART_pybind11_patch.h000066400000000000000000000060351353046746100210110ustar00rootroot00000000000000#define MYPYBIND11_PLUGIN_IMPL(name) \ extern "C" PYBIND11_EXPORT PyObject *PyInit_##name() #define MYPYBIND11_CHECK_PYTHON_VERSION \ { \ const char *compiled_ver = PYBIND11_TOSTRING(PY_MAJOR_VERSION) \ "." PYBIND11_TOSTRING(PY_MINOR_VERSION); \ const char *runtime_ver = Py_GetVersion(); \ size_t len = std::strlen(compiled_ver); \ if (std::strncmp(runtime_ver, compiled_ver, len) != 0 \ || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) { \ PyErr_Format(PyExc_ImportError, \ "Python version mismatch: module was compiled for Python %s, " \ "but the interpreter version is incompatible: %s.", \ compiled_ver, runtime_ver); \ return nullptr; \ } \ } #define MYPYBIND11_CATCH_INIT_EXCEPTIONS \ catch (pybind11::error_already_set &e) { \ PyErr_SetString(PyExc_ImportError, e.what()); \ return nullptr; \ } catch (const std::exception &e) { \ PyErr_SetString(PyExc_ImportError, e.what()); \ return nullptr; \ } \ #define MYPYBIND11_MODULE(name, variable) \ static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::mymodule &); \ MYPYBIND11_PLUGIN_IMPL(name) { \ MYPYBIND11_CHECK_PYTHON_VERSION; \ auto m = pybind11::mymodule(PYBIND11_TOSTRING(name)); \ try { \ PYBIND11_CONCAT(pybind11_init_, name)(m); \ return m.ptr(); \ } MYPYBIND11_CATCH_INIT_EXCEPTIONS; \ } \ void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::mymodule &variable) #if PY_MAJOR_VERSION < 3 class A {}; // dummy class #define MYPYBIND11_MODULE_DESTRUCTOR_IMPLEMENT \ py::class_(m, "BaseClass"); \ py::cpp_function cleanup_callback( \ [](py::handle weakref) { \ cleanup_memory(); \ weakref.dec_ref(); \ } \ ); \ (void) py::weakref(m.attr("BaseClass"), cleanup_callback).release() #else # define MYPYBIND11_MODULE_DESTRUCTOR_IMPLEMENT static int pyBART_clear(PyObject *m); static int pyBART_traverse(PyObject *m, visitproc visit, void *arg); #endif /* PY_MAJOR_VERSION < 3 */ NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// Wrapper for Python extension modules class mymodule : public module { public: PYBIND11_OBJECT_DEFAULT(mymodule, module, PyModule_Check) /// Create a new top-level Python module with the given name and docstring explicit mymodule(const char *name, const char *doc = nullptr) { if (!options::show_user_defined_docstrings()) doc = nullptr; #if PY_MAJOR_VERSION >= 3 PyModuleDef *def = new PyModuleDef(); std::memset(def, 0, sizeof(PyModuleDef)); def->m_name = name; def->m_doc = doc; def->m_size = -1; def->m_traverse = pyBART_traverse; def->m_clear = pyBART_clear; Py_INCREF(def); m_ptr = PyModule_Create(def); #else m_ptr = Py_InitModule3(name, nullptr, doc); #endif if (m_ptr == nullptr) pybind11_fail("Internal error in mymodule::mymodule()"); inc_ref(); } }; NAMESPACE_END(PYBIND11_NAMESPACE) bart-0.5.00/src/repmat.c000066400000000000000000000026371353046746100147700ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Author: * 2012-2014 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #define DIMS 16 static const char usage_str[] = "dimension repetitions "; static const char help_str[] = "Repeat input array multiple times along a certain dimension.\n"; int main_repmat(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); long in_dims[DIMS]; long out_dims[DIMS]; complex float* in_data = load_cfl(argv[3], DIMS, in_dims); int dim = atoi(argv[1]); int rep = atoi(argv[2]); assert(dim < DIMS); assert(rep >= 0); assert(1 == in_dims[dim]); md_copy_dims(DIMS, out_dims, in_dims); out_dims[dim] = rep; complex float* out_data = create_cfl(argv[4], DIMS, out_dims); long in_strs[DIMS]; long out_strs[DIMS]; md_calc_strides(DIMS, in_strs, in_dims, CFL_SIZE); md_calc_strides(DIMS, out_strs, out_dims, CFL_SIZE); md_copy2(DIMS, out_dims, out_strs, out_data, in_strs, in_data, CFL_SIZE); unmap_cfl(DIMS, out_dims, out_data); unmap_cfl(DIMS, in_dims, in_data); return 0; } bart-0.5.00/src/reshape.c000066400000000000000000000034221353046746100151200ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Martin Uecker */ #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #define DIMS 16 #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "flags dim1 ... dimN "; static const char help_str[] = "Reshape selected dimensions.\n"; int main_reshape(int argc, char* argv[]) { cmdline(&argc, argv, 3, 100, usage_str, help_str, 0, NULL); num_init(); unsigned int flags = atoi(argv[1]); unsigned int n = bitcount(flags); assert((int)n + 3 == argc - 1); long in_dims[DIMS]; long in_strs[DIMS]; long out_dims[DIMS]; long out_strs[DIMS]; complex float* in_data = load_cfl(argv[n + 2], DIMS, in_dims); md_calc_strides(DIMS, in_strs, in_dims, CFL_SIZE); md_copy_dims(DIMS, out_dims, in_dims); unsigned int j = 0; for (unsigned int i = 0; i < DIMS; i++) if (MD_IS_SET(flags, i)) out_dims[i] = atoi(argv[j++ + 2]); assert(j == n); assert(md_calc_size(DIMS, in_dims) == md_calc_size(DIMS, out_dims)); md_calc_strides(DIMS, out_strs, out_dims, CFL_SIZE); for (unsigned int i = 0; i < DIMS; i++) if (!(MD_IS_SET(flags, i) || (in_strs[i] == out_strs[i]))) error("Dimensions are not consistent at index %d.\n", i); complex float* out_data = create_cfl(argv[n + 3], DIMS, out_dims); md_copy(DIMS, in_dims, out_data, in_data, CFL_SIZE); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); return 0; } bart-0.5.00/src/resize.c000066400000000000000000000033001353046746100147650ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * 2014 Jonathan Tamir */ #include #include #include "num/multind.h" #include "num/init.h" #include "misc/resize.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "dim1 size1 ... dimn sizen "; static const char help_str[] = "Resizes an array along dimensions to sizes by truncating or zero-padding."; int main_resize(int argc, char* argv[]) { bool center = false; const struct opt_s opts[] = { OPT_SET('c', ¢er, "center"), }; cmdline(&argc, argv, 4, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int N = DIMS; int count = argc - 3; assert((count > 0) && (count % 2 == 0)); long in_dims[N]; long out_dims[N]; void* in_data = load_cfl(argv[argc - 2], N, in_dims); md_copy_dims(N, out_dims, in_dims); for (int i = 0; i < count; i += 2) { unsigned int dim = atoi(argv[i + 1]); unsigned int size = atoi(argv[i + 2]); assert(dim < N); assert(size >= 1); out_dims[dim] = size; } void* out_data = create_cfl(argv[argc - 1], N, out_dims); (center ? md_resize_center : md_resize)(N, out_dims, out_data, in_dims, in_data, CFL_SIZE); unmap_cfl(N, in_dims, in_data); unmap_cfl(N, out_dims, out_data); return 0; } bart-0.5.00/src/rof.c000066400000000000000000000040101353046746100142510ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Martin Uecker * * * Rudin LI, Osher S, Fatemi E. Nonlinear total variation based * noise removal algorithms, Physica D: Nonlinear Phenomena * 60:259-268 (1992) * */ #include #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "num/ops_p.h" #include "num/init.h" #include "linops/linop.h" #include "linops/someops.h" #include "linops/grad.h" #include "misc/mmio.h" #include "misc/misc.h" #include "iter/prox.h" #include "iter/thresh.h" #include "iter/iter2.h" #include "iter/iter.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Perform total variation denoising along dims .\n"; int main_rof(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); long dims[DIMS]; float lambda = atof(argv[1]); int flags = atoi(argv[2]); complex float* in_data = load_cfl(argv[3], DIMS, dims); complex float* out_data = create_cfl(argv[4], DIMS, dims); auto id_op = linop_identity_create(DIMS, dims); const struct linop_s* grad_op = linop_grad_create(DIMS, dims, DIMS, flags); auto thresh_prox = prox_thresh_create(DIMS + 1, linop_codomain(grad_op)->dims, lambda, MD_BIT(DIMS)); struct iter_admm_conf conf = iter_admm_defaults; conf.maxiter = 50; conf.rho = .1; iter2_admm(CAST_UP(&conf), id_op->forward, 1, MAKE_ARRAY(thresh_prox), MAKE_ARRAY(grad_op), NULL, NULL, 2 * md_calc_size(DIMS, dims), (float*)out_data, (const float*)in_data, NULL); linop_free(id_op); linop_free(grad_op); operator_p_free(thresh_prox); unmap_cfl(DIMS, dims, in_data); unmap_cfl(DIMS, dims, out_data); return 0; } bart-0.5.00/src/rss.c000066400000000000000000000022021353046746100142730ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Calculates root of sum of squares along selected dimensions.\n"; int main_rss(int argc, char* argv[argc]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); long dims[DIMS]; complex float* data = load_cfl(argv[2], DIMS, dims); int flags = atoi(argv[1]); assert(0 <= flags); long odims[DIMS]; md_select_dims(DIMS, ~flags, odims, dims); complex float* out = create_cfl(argv[3], DIMS, odims); md_zrss(DIMS, dims, flags, out, data); unmap_cfl(DIMS, dims, data); unmap_cfl(DIMS, odims, out); return 0; } bart-0.5.00/src/sake.c000066400000000000000000000040241353046746100144130ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013, 2015 Martin Uecker * * * Peter J. Shin, Peder E.Z. Larson, Michael A. Ohliger, Michael Elad, * John M. Pauly, Daniel B. Vigneron and Michael Lustig, Calibrationless * Parallel Imaging Reconstruction Based on Structured Low-Rank Matrix * Completion, 2013, accepted to Magn Reson Med. * * Zhongyuan Bi, Martin Uecker, Dengrong Jiang, Michael Lustig, and Kui Ying. * Robust Low-rank Matrix Completion for sparse motion correction in auto * calibration PI. Annual Meeting ISMRM, Salt Lake City 2013, * In Proc. Intl. Soc. Mag. Recon. Med 21; 2584 (2013) */ #include #include #include "num/init.h" #include "num/multind.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/opts.h" #include "sake/sake.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Use SAKE algorithm to recover a full k-space from undersampled\n" "data using low-rank matrix completion."; int main_sake(int argc, char* argv[]) { float alpha = 0.22; int iter = 50; float lambda = 1.; const struct opt_s opts[] = { OPT_INT('i', &iter, "iter", "tnumber of iterations"), OPT_FLOAT('s', &alpha, "size", "rel. size of the signal subspace"), OPT_FLOAT('o', &lambda, "", "()"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); assert((0. <= alpha) && (alpha <= 1.)); assert(iter >= 0); assert((0. <= lambda) && (lambda <= 1.)); long dims[DIMS]; num_init(); complex float* in_data = load_cfl(argv[1], DIMS, dims); complex float* out_data = create_cfl(argv[2], DIMS, dims); lrmc(alpha, iter, lambda, DIMS, dims, out_data, in_data); unmap_cfl(DIMS, dims, out_data); unmap_cfl(DIMS, dims, in_data); return 0; } bart-0.5.00/src/sake/000077500000000000000000000000001353046746100142475ustar00rootroot00000000000000bart-0.5.00/src/sake/sake.c000066400000000000000000000141351353046746100153420ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker * 2014 Jonathan Tamir * * * Peter J. Shin, Peder E.Z. Larson, Michael A. Ohliger, Michael Elad, * John M. Pauly, Daniel B. Vigneron and Michael Lustig, Calibrationless * Parallel Imaging Reconstruction Based on Structured Low-Rank Matrix * Completion, Magn Reson Med. Epub (2014) * * Zhongyuan Bi, Martin Uecker, Dengrong Jiang, Michael Lustig, and Kui Ying. * Robust Low-rank Matrix Completion for sparse motion correction in auto * calibration PI. Annual Meeting ISMRM, Salt Lake City 2013, * In Proc. Intl. Soc. Mag. Recon. Med 21; 2584 (2013) */ #include #include #include #include #include "num/lapack.h" #include "num/linalg.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/casorati.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/mri.h" #include "sake.h" #undef DIMS // FIXME #define DIMS 16 #if 0 static float thresh(float lambda, float x) { float norm = fabs(x); float red = norm - lambda; return (red > 0.) ? ((red / norm) * (x)) : 0.; } #endif static complex float cthresh(float lambda, complex float x) { float norm = cabsf(x); float red = norm - lambda; return (red > 0.) ? ((red / norm) * x) : 0.; } static void robust_consistency(float lambda, const long dims[5], complex float* dst, const complex float* pattern, const complex float* kspace) { assert(1 == dims[4]); size_t size = md_calc_size(5, dims); for (unsigned int i = 0; i < size; i++) if (1. == pattern[i % (size / dims[3])]) dst[i] = kspace[i] + cthresh(lambda, dst[i] - kspace[i]); } #if 1 #define RAVINE #endif #ifdef RAVINE static void ravine(unsigned int N, const long dims[N], float* ftp, complex float* xa, complex float* xb) { float ft = *ftp; float tfo = ft; ft = (1.f + sqrtf(1.f + 4.f * ft * ft)) / 2.f; *ftp = ft; md_swap(N, dims, xa, xb, CFL_SIZE); complex float val = (1.f - tfo) / ft - 1.f; long dims1[N]; md_singleton_dims(N, dims1); long strs1[N]; long strs[N]; md_calc_strides(N, strs1, dims1, CFL_SIZE); md_calc_strides(N, strs, dims, CFL_SIZE); md_zfmac2(N, dims, strs, xa, strs1, &val, strs, xa); val *= -1.; md_zfmac2(N, dims, strs, xa, strs1, &val, strs, xb); } #endif static void lowrank(float alpha, int D, const long dims[D], complex float* matrix) { assert(1 == dims[MAPS_DIM]); debug_printf(DP_DEBUG3, "mat_dims = \t"); debug_print_dims(DP_DEBUG3, D, dims); long kern_min[4] = { 6, 6, 6, dims[COIL_DIM] }; long kern_dims[D]; md_set_dims(D, kern_dims, 1); md_min_dims(4, ~0u, kern_dims, kern_min, dims); debug_printf(DP_DEBUG3, "kern_dims = \t"); debug_print_dims(DP_DEBUG3, D, kern_dims); long calmat_dims[2]; casorati_dims(D, calmat_dims, kern_dims, dims); debug_printf(DP_DEBUG3, "calmat_dims = \t"); debug_print_dims(DP_DEBUG3, 2, calmat_dims); complex float* calmat = md_alloc(2, calmat_dims, CFL_SIZE); long str[D]; md_calc_strides(D, str, dims, CFL_SIZE); casorati_matrix(D, kern_dims, calmat_dims, calmat, dims, str, matrix); int N = calmat_dims[0]; int M = calmat_dims[1]; debug_printf(DP_INFO, "%dx%d\n", N, M); if (-1. != alpha) { long dimsU[2] = { N, N }; long dimsV[2] = { M, M }; complex float* U = md_alloc(2, dimsU, CFL_SIZE); complex float* VT = md_alloc(2, dimsV, CFL_SIZE); // complex float* U = create_cfl("U", 2, dimsU); // complex float* VT = create_cfl("VT", 2, dimsV); float* S = xmalloc(MIN(N, M) * sizeof(float)); debug_printf(DP_INFO, "SVD..\n"); //lapack_svd(N, M, (complex float (*)[M])U, (complex float (*)[N])VT, S, (complex float (*)[N])calmat); lapack_svd_econ(N, M, (complex float (*)[M])U, (complex float (*)[N])VT, S, (complex float (*)[N])calmat); // CHECK debug_printf(DP_INFO, "done.\n"); // put it back together long dimU2[2] = { N, MIN(N, M) }; long dimV2[2] = { MIN(N, M), M }; complex float* U2 = md_alloc(2, dimU2, CFL_SIZE); complex float* V2 = md_alloc(2, dimV2, CFL_SIZE); md_resize(2, dimU2, U2, dimsU, U, CFL_SIZE); md_resize(2, dimV2, V2, dimsV, VT, CFL_SIZE); for (int i = 0; i < M; i++) { // printf("%f\t", S[i]); for (int j = 0; j < MIN(N, M); j++) //V2[i * MIN(N, M) + j] *= thresh(alpha, S[j]); V2[i * MIN(N, M) + j] *= (j < alpha * (float)MIN(N, M)) ? S[j] : 0.; // thresh(alpha, S[j]); } mat_mul(M, MIN(M, N), N, (complex float (*)[N])calmat, (const complex float (*)[MIN(M, N)])V2, (const complex float (*)[N])U2); md_free(U); md_free(U2); md_free(VT); md_free(V2); xfree(S); } md_clear(D, dims, matrix, CFL_SIZE); casorati_matrixH(D, kern_dims, dims, str, matrix, calmat_dims, calmat); md_zsmul(D, dims, matrix, matrix, 1. / (double)md_calc_size(3, kern_dims)); // FIXME: not right at the border md_free(calmat); } void lrmc(float alpha, int iter, float lambda, int N, const long dims[N], complex float* out, const complex float* in) { long dims1[N]; md_select_dims(N, ~COIL_FLAG, dims1, dims); md_copy(N, dims, out, in, CFL_SIZE); complex float* pattern = md_alloc(N, dims1, CFL_SIZE); //assert(5 == N); estimate_pattern(N, dims, COIL_FLAG, pattern, in); complex float* comp = md_alloc(N, dims1, CFL_SIZE); md_zfill(N, dims1, comp, 1.); lowrank(-1., N, dims1, comp); #ifdef RAVINE complex float* o = md_alloc(N, dims, CFL_SIZE); md_clear(N, dims, o, CFL_SIZE); float fl = 1.; #endif long strs1[N]; md_calc_strides(N, strs1, dims1, CFL_SIZE); long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); for (int i = 0; i < iter; i++) { debug_printf(DP_INFO, "%d\n", i); if (-1. != lambda) robust_consistency(lambda, dims, out, pattern, in); else data_consistency(dims, out, pattern, in, out); lowrank(alpha, N, dims, out); md_zdiv2(N, dims, strs, out, strs, out, strs1, comp); #ifdef RAVINE ravine(N, dims, &fl, out, o); #endif } debug_printf(DP_INFO, "Done.\n"); #ifdef RAVINE md_free(o); #endif md_free(comp); md_free(pattern); } bart-0.5.00/src/sake/sake.h000066400000000000000000000002771353046746100153510ustar00rootroot00000000000000 #include "misc/cppwrap.h" extern void lrmc(float alpha, int iter, float lambda, int N, const long dims[__VLA(N)], _Complex float* out, const _Complex float* in); #include "misc/cppwrap.h" bart-0.5.00/src/saxpy.c000066400000000000000000000025741353046746100146440ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "scale "; static const char help_str[] = "Multiply input1 with scale factor and add input2.\n"; int main_saxpy(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); complex float scale; if (0 != parse_cfl(&scale, argv[1])) { fprintf(stderr, "ERROR: %s is not a complex number.\n", argv[1]); return 1; } const int N = DIMS; long dims1[N]; long dims2[N]; complex float* data1 = load_cfl(argv[2], N, dims1); complex float* data2 = load_cfl(argv[3], N, dims2); for (int i = 0; i < N; i++) assert(dims1[i] == dims2[i]); complex float* out = create_cfl(argv[4], N, dims2); #pragma omp parallel for for (long i = 0; i < md_calc_size(N, dims1); i++) out[i] = scale * data1[i] + data2[i]; unmap_cfl(N, dims1, data1); unmap_cfl(N, dims2, data2); unmap_cfl(N, dims2, out); return 0; } bart-0.5.00/src/scale.c000066400000000000000000000023071353046746100145610ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "factor "; static const char help_str[] = "Scale array by {factor}. The scale factor can be a complex number.\n"; int main_scale(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); complex float scale; // = atof(argv[1]); if (0 != parse_cfl(&scale, argv[1])) { fprintf(stderr, "ERROR: scale factor %s is not a number.\n", argv[1]); return 1; } const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); md_zsmul(N, dims, odata, idata, scale); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/sdot.c000066400000000000000000000023361353046746100144450ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012, 2015 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Compute dot product along selected dimensions."; int main_sdot(int argc, char* argv[]) { cmdline(&argc, argv, 2, 2, usage_str, help_str, 0, NULL); num_init(); int N = DIMS; long in1_dims[N]; long in2_dims[N]; complex float* in1_data = load_cfl(argv[1], N, in1_dims); complex float* in2_data = load_cfl(argv[2], N, in2_dims); for (int i = 0; i < N; i++) assert(in1_dims[i] == in2_dims[i]); // compute scalar product complex float value = md_zscalar(N, in1_dims, in1_data, in2_data); bart_printf("%+e%+ei\n", crealf(value), cimagf(value)); unmap_cfl(N, in1_dims, in1_data); unmap_cfl(N, in2_dims, in2_data); return 0; } bart-0.5.00/src/sense/000077500000000000000000000000001353046746100144415ustar00rootroot00000000000000bart-0.5.00/src/sense/model.c000066400000000000000000000170251353046746100157120ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2014 Frank Ong * * * Ra JB, Rim CY. Fast imaging using subencoding data sets from multiple detectors. * Magn Reson Med 1993; 30:142-145. * * Pruessmann KP, Weiger M, Scheidegger MB, Boesiger P. SENSE: Sensitivity encoding for fast * MRI. Magn Reson Med 1999; 42:952-962. * * Pruessmann KP, Weiger M, Boernert P, Boesiger P. Advances in sensitivity * encoding with arbitrary k-space trajectories. * Magn Reson Med 2001; 46:638-651. * * Uecker M, Lai P, Murphy MJ, Virtue P, Elad M, Pauly JM, Vasanawala SS, Lustig M. * ESPIRiT - An Eigenvalue Approach to Autocalibrating Parallel MRI: Where SENSE * meets GRAPPA. Magn Reson Med 2014; 71:990-1001. * */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/ops.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "linops/linop.h" #include "linops/someops.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "model.h" /** * data structure for holding the sense data. * * @param max_dims maximal dimensions * @param dims_mps maps dimensions * @param dims_ksp kspace dimensions * @param img_dims final image dimensions * @param strs_mps strides for maps * @param strs_ksp strides for kspace * @param strs_img strides for image * @param sens sensitivity maps */ struct maps_data { INTERFACE(linop_data_t); long max_dims[DIMS]; long mps_dims[DIMS]; long ksp_dims[DIMS]; long img_dims[DIMS]; long strs_mps[DIMS]; long strs_ksp[DIMS]; long strs_img[DIMS]; /*const*/ complex float* sens; #ifdef USE_CUDA const complex float* gpu_sens; #endif complex float* norm; }; static DEF_TYPEID(maps_data); #ifdef USE_CUDA static const complex float* get_sens(const struct maps_data* data, bool gpu) { const complex float* sens = data->sens; if (gpu) { if (NULL == data->gpu_sens) ((struct maps_data*)data)->gpu_sens = md_gpu_move(DIMS, data->mps_dims, data->sens, CFL_SIZE); sens = data->gpu_sens; } return sens; } #endif static void maps_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(maps_data, _data); #ifdef USE_CUDA const complex float* sens = get_sens(data, cuda_ondevice(src)); #else const complex float* sens = data->sens; #endif md_clear(DIMS, data->ksp_dims, dst, CFL_SIZE); md_zfmac2(DIMS, data->max_dims, data->strs_ksp, dst, data->strs_img, src, data->strs_mps, sens); } static void maps_apply_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(maps_data, _data); #ifdef USE_CUDA const complex float* sens = get_sens(data, cuda_ondevice(src)); #else const complex float* sens = data->sens; #endif // dst = sum( conj(sens) .* tmp ) md_clear(DIMS, data->img_dims, dst, CFL_SIZE); md_zfmacc2(DIMS, data->max_dims, data->strs_img, dst, data->strs_ksp, src, data->strs_mps, sens); } static void maps_init_normal(struct maps_data* data) { if (NULL != data->norm) return; // FIXME: gpu/cpu mixed use data->norm = md_alloc_sameplace(DIMS, data->img_dims, CFL_SIZE, data->sens); md_zrss(DIMS, data->mps_dims, COIL_FLAG, data->norm, data->sens); md_zmul(DIMS, data->img_dims, data->norm, data->norm, data->norm); } static void maps_apply_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { auto data = CAST_DOWN(maps_data, _data); maps_init_normal(data); md_zmul(DIMS, data->img_dims, dst, src, data->norm); } /* * ( AT A + lambda I) x = b */ static void maps_apply_pinverse(const linop_data_t* _data, float lambda, complex float* dst, const complex float* src) { auto data = CAST_DOWN(maps_data, _data); maps_init_normal(data); md_zsadd(DIMS, data->img_dims, data->norm, data->norm, lambda); md_zdiv(DIMS, data->img_dims, dst, src, data->norm); md_zsadd(DIMS, data->img_dims, data->norm, data->norm, -lambda); } static void maps_free_data(const linop_data_t* _data) { const auto data = CAST_DOWN(maps_data, _data); md_free(data->sens); if (NULL != data->norm) md_free(data->norm); #ifdef USE_CUDA if (NULL != data->gpu_sens) md_free(data->gpu_sens); #endif xfree(data); } static struct maps_data* maps_create_data(const long max_dims[DIMS], unsigned int sens_flags, const complex float* sens) { PTR_ALLOC(struct maps_data, data); SET_TYPEID(maps_data, data); // maximal dimensions md_copy_dims(DIMS, data->max_dims, max_dims); // sensitivity dimensions md_select_dims(DIMS, sens_flags, data->mps_dims, max_dims); md_calc_strides(DIMS, data->strs_mps, data->mps_dims, CFL_SIZE); md_select_dims(DIMS, ~MAPS_FLAG, data->ksp_dims, max_dims); md_calc_strides(DIMS, data->strs_ksp, data->ksp_dims, CFL_SIZE); md_select_dims(DIMS, ~COIL_FLAG, data->img_dims, max_dims); md_calc_strides(DIMS, data->strs_img, data->img_dims, CFL_SIZE); complex float* nsens = md_alloc(DIMS, data->mps_dims, CFL_SIZE); md_copy(DIMS, data->mps_dims, nsens, sens, CFL_SIZE); data->sens = nsens; #ifdef USE_CUDA data->gpu_sens = NULL; #endif data->norm = NULL; return PTR_PASS(data); } /** * Create maps operator, m = S x * * @param max_dims maximal dimensions across all data structures * @param sens_flags active map dimensions * @param sens sensitivities */ struct linop_s* maps_create(const long max_dims[DIMS], unsigned int sens_flags, const complex float* sens) { auto data = maps_create_data(max_dims, sens_flags, sens); // scale the sensitivity maps by the FFT scale factor fftscale(DIMS, data->mps_dims, FFT_FLAGS, data->sens, data->sens); return linop_create(DIMS, data->ksp_dims, DIMS, data->img_dims, CAST_UP(data), maps_apply, maps_apply_adjoint, maps_apply_normal, maps_apply_pinverse, maps_free_data); } struct linop_s* maps2_create(const long coilim_dims[DIMS], const long maps_dims[DIMS], const long img_dims[DIMS], const complex float* maps) { long max_dims[DIMS]; unsigned int sens_flags = 0; for (unsigned int i = 0; i < DIMS; i++) if (1 != maps_dims[i]) sens_flags = MD_SET(sens_flags, i); assert(1 == coilim_dims[MAPS_DIM]); assert(1 == img_dims[COIL_DIM]); assert(maps_dims[COIL_DIM] == coilim_dims[COIL_DIM]); assert(maps_dims[MAPS_DIM] == img_dims[MAPS_DIM]); for (unsigned int i = 0; i < DIMS; i++) max_dims[i] = MAX(coilim_dims[i], MAX(maps_dims[i], img_dims[i])); struct maps_data* data = maps_create_data(max_dims, sens_flags, maps); return linop_create(DIMS, coilim_dims, DIMS, img_dims, CAST_UP(data), maps_apply, maps_apply_adjoint, maps_apply_normal, maps_apply_pinverse, maps_free_data); } /** * Create sense operator, y = F S x, * where F is the Fourier transform and S is the sensitivity maps * * @param max_dims maximal dimensions across all data structures * @param sens_flags active map dimensions * @param sens sensitivities */ struct linop_s* sense_init(const long max_dims[DIMS], unsigned int sens_flags, const complex float* sens) { long ksp_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, ksp_dims, max_dims); struct linop_s* fft = linop_fft_create(DIMS, ksp_dims, FFT_FLAGS); struct linop_s* maps = maps_create(max_dims, sens_flags, sens); struct linop_s* sense_op = linop_chain(maps, fft); linop_free(fft); linop_free(maps); return sense_op; } bart-0.5.00/src/sense/model.h000066400000000000000000000013551353046746100157160ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus extern "C" { #endif #include "misc/mri.h" struct operator_s; struct vec_ops; extern struct linop_s* sense_init(const long max_dims[DIMS], unsigned int sens_flags, const complex float* sens); extern struct linop_s* maps_create(const long max_dims[DIMS], unsigned int sens_flags, const complex float* sens); extern struct linop_s* maps2_create(const long coilim_dims[DIMS], const long maps_dims[DIMS], const long img_dims[DIMS], const complex float* maps); #ifdef __cplusplus } #endif bart-0.5.00/src/sense/optcom.c000066400000000000000000000141121353046746100161050ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Author: * 2012 Martin Uecker */ #include #include #include #include #include "sense/model.h" #include "linops/linop.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "misc/mri.h" #include "misc/misc.h" #include "misc/debug.h" #include "optcom.h" /** * Optimally combine coil images. * * Assumptions: * @param data fully sampled data * @param sens physical (unormalized) coil sensitivites * @param alpha the best estimator has alpha > 0. */ void optimal_combine(const long dims[DIMS], float alpha, complex float* image, const complex float* sens, const complex float* data) { long dims_one[DIMS]; long dims_img[DIMS]; long dims_cim[DIMS]; md_select_dims(DIMS, ~(COIL_FLAG|MAPS_FLAG), dims_one, dims); md_select_dims(DIMS, ~(COIL_FLAG), dims_img, dims); md_select_dims(DIMS, ~(MAPS_FLAG), dims_cim, dims); const struct linop_s* sense_data = sense_init(dims, FFT_FLAGS|COIL_FLAG|MAPS_FLAG, sens); linop_adjoint(sense_data, DIMS, dims_img, image, DIMS, dims_cim, data); linop_free(sense_data); complex float* norm = md_alloc(DIMS, dims_img, CFL_SIZE); md_zrss(DIMS, dims, COIL_FLAG, norm, sens); long imsize = md_calc_size(DIMS, dims_img); for (unsigned int i = 0; i < imsize; i++) image[i] /= (powf(cabsf(norm[i]), 2.) + alpha); md_free(norm); } void rss_combine(const long dims[DIMS], complex float* image, const complex float* data) { complex float* tmp = md_alloc_sameplace(DIMS, dims, CFL_SIZE, data); ifft(DIMS, dims, FFT_FLAGS, tmp, data); fftscale(DIMS, dims, FFT_FLAGS, tmp, tmp); md_zrss(DIMS, dims, COIL_FLAG, image, tmp); md_free(tmp); } static int compare_cmpl_magn(const void* a, const void* b) { return (int)copysignf(1., (cabsf(*(complex float*)a) - cabsf(*(complex float*)b))); } float estimate_scaling_norm(float rescale, long imsize, complex float* tmpnorm, bool compat) { qsort(tmpnorm, (size_t)imsize, sizeof(complex float), compare_cmpl_magn); float median = cabsf(tmpnorm[imsize / 2]) / rescale; //median float p90 = cabsf(tmpnorm[(int)trunc(imsize * 0.9)]) / rescale; float max = cabsf(tmpnorm[imsize - 1]) / rescale; float scale = ((max - p90) < 2 * (p90 - median)) ? p90 : max; if (compat) scale = median; debug_printf(DP_DEBUG1, "Scaling: %f%c (max = %f/p90 = %f/median = %f)\n", scale, (scale == max) ? '!' : ' ', max, p90, median); return scale; } extern float estimate_scaling_cal(const long dims[DIMS], const complex float* sens, const long cal_dims[DIMS], const complex float* cal_data, bool compat) { long img_dims[DIMS]; md_select_dims(DIMS, ~COIL_FLAG, img_dims, cal_dims); long imsize = md_calc_size(DIMS, img_dims); complex float* tmp1 = md_alloc(DIMS, img_dims, CFL_SIZE); float rescale = sqrtf((float)dims[0] / (float)cal_dims[0]) * sqrtf((float)dims[1] / (float)cal_dims[1]) * sqrtf((float)dims[2] / (float)cal_dims[2]); if (NULL == sens) { rss_combine(cal_dims, tmp1, cal_data); } else { optimal_combine(cal_dims, 0., tmp1, sens, cal_data); } float scale = estimate_scaling_norm(rescale, imsize, tmp1, compat); md_free(tmp1); return scale; } static float estimate_scaling_internal(const long dims[DIMS], const complex float* sens, const long strs[DIMS], const complex float* data, bool compat) { assert(1 == dims[MAPS_DIM]); long small_dims[DIMS]; long cal_size[3] = { 32, 32, 32 }; // maybe we should just extract a fixed-sized block here? complex float* tmp = extract_calib2(small_dims, cal_size, dims, strs, data, false); float scaling = estimate_scaling_cal(dims, sens, small_dims, tmp, compat); md_free(tmp); return scaling; } float estimate_scaling2(const long dims[DIMS], const complex float* sens, const long strs[DIMS], const complex float* data2) { return estimate_scaling_internal(dims, sens, strs, data2, false); } float estimate_scaling(const long dims[DIMS], const complex float* sens, const complex float* data2) { long strs[DIMS]; md_calc_strides(DIMS, strs, dims, CFL_SIZE); return estimate_scaling2(dims, sens, strs, data2); } float estimate_scaling_old2(const long dims[DIMS], const complex float* sens, const long strs[DIMS], const complex float* data) { return estimate_scaling_internal(dims, sens, strs, data, true); } void fake_kspace(const long dims[DIMS], complex float* kspace, const complex float* sens, const complex float* image) { long dims_one[DIMS]; long dims_img[DIMS]; long dims_ksp[DIMS]; md_select_dims(DIMS, ~(COIL_FLAG | MAPS_FLAG), dims_one, dims); md_select_dims(DIMS, ~COIL_FLAG, dims_img, dims); md_select_dims(DIMS, ~MAPS_FLAG, dims_ksp, dims); const struct linop_s* sense_data = sense_init(dims, FFT_FLAGS|COIL_FLAG|MAPS_FLAG, sens); linop_forward(sense_data, DIMS, dims_ksp, kspace, DIMS, dims_img, image); linop_free(sense_data); } void replace_kspace(const long dims[DIMS], complex float* out, const complex float* kspace, const complex float* sens, const complex float* image) { long dims_one[DIMS]; long dims_img[DIMS]; long dims_ksp[DIMS]; md_select_dims(DIMS, ~(COIL_FLAG|MAPS_FLAG), dims_one, dims); md_select_dims(DIMS, ~(COIL_FLAG), dims_img, dims); md_select_dims(DIMS, ~(MAPS_FLAG), dims_ksp, dims); complex float* data = md_alloc(DIMS, dims_ksp, CFL_SIZE); fake_kspace(dims, data, sens, image); complex float* pattern = md_alloc(DIMS, dims_one, CFL_SIZE); estimate_pattern(DIMS, dims_ksp, COIL_FLAG, pattern, kspace); data_consistency(dims_ksp, out, pattern, kspace, data); md_free(pattern); md_free(data); } void replace_kspace2(const long dims[DIMS], complex float* out, const complex float* kspace, const complex float* sens, const complex float* image) { long dims_ksp[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, dims_ksp, dims); complex float* data = md_alloc(DIMS, dims_ksp, CFL_SIZE); replace_kspace(dims, data, kspace, sens, image); rss_combine(dims, out, data); // optimal_combine(dims, 0.1, out, sens, data); md_free(data); } bart-0.5.00/src/sense/optcom.h000066400000000000000000000031561353046746100161200ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifdef __cplusplus extern "C" { #endif #include #include "misc/mri.h" extern void rss_combine(const long dims[DIMS], _Complex float* image, const _Complex float* data); extern void optimal_combine(const long dims[DIMS], float alpha, _Complex float* image, const _Complex float* sens, const _Complex float* data); extern float estimate_scaling_norm(float rescale, long imsize, _Complex float* tmpnorm, bool compat); extern float estimate_scaling(const long dims[DIMS], const _Complex float* sens, const _Complex float* data); extern float estimate_scaling2(const long dims[DIMS], const _Complex float* sens, const long strs[DIMS], const _Complex float* data); extern float estimate_scaling_old2(const long dims[DIMS], const _Complex float* sens, const long strs[DIMS], const _Complex float* data); extern void fake_kspace(const long dims[DIMS], _Complex float* kspace, const _Complex float* sens, const _Complex float* image); extern void replace_kspace(const long dims[DIMS], _Complex float* out, const _Complex float* kspace, const _Complex float* sens, const _Complex float* image); extern void replace_kspace2(const long dims[DIMS], _Complex float* out, const _Complex float* kspace, const _Complex float* sens, const _Complex float* image); extern float estimate_scaling_cal(const long dims[DIMS], const _Complex float* sens, const long cal_dims[DIMS], const _Complex float* cal_data, _Bool compat); #ifdef __cplusplus } #endif bart-0.5.00/src/sense/pocs.c000066400000000000000000000211501353046746100155500ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * Copyright 2016-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2018 Martin Uecker * 2014 Jonathan Tamir * * * Samsonov AA, Kholmovski EG, Parker DL, Johnson CR. POCSENSE: POCS-based * reconstruction for sensitivity encoded magnetic resonance imaging. * Magn Reson Med 2004; 52:1397–1406. * */ #include #include #include #include #include "misc/misc.h" #include "misc/mri.h" #include "misc/debug.h" #include "misc/types.h" #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/ops_p.h" #include "num/ops.h" #include "linops/linop.h" #include "iter/iter.h" #include "iter/prox.h" #include "iter/monitor.h" #include "sense/model.h" #include "pocs.h" struct data { INTERFACE(operator_data_t); const struct linop_s* sense_op; complex float* tmp; float alpha; // l1 or l2 regularization float lambda; // robust consistency const struct operator_p_s* thresh; const complex float* kspace; const complex float* pattern; const complex float* fftmod_mat; long dims_ksp[DIMS]; long dims_pat[DIMS]; long strs_ksp[DIMS]; long strs_pat[DIMS]; }; static DEF_TYPEID(data); static void xupdate_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(data, _data); UNUSED(mu); md_zsmul(DIMS, data->dims_ksp, dst, src, 1. / (data->alpha == 0 ? 2. : 3.)); } static complex float cthresh(float lambda, complex float x) { float norm = cabsf(x); float red = norm - lambda; return (red > 0.) ? ((red / norm) * x) : 0.; } static void robust_consistency(float lambda, const long dims[DIMS], complex float* dst, const complex float* pattern, const complex float* kspace) { assert(1 == dims[MAPS_DIM]); size_t size = md_calc_size(DIMS, dims); for (unsigned int i = 0; i < size; i++) if (1. == pattern[i % (size / dims[COIL_DIM])]) dst[i] = kspace[i] + cthresh(lambda, dst[i] - kspace[i]); } static void sparsity_proj_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { const auto data = CAST_DOWN(data, _data); const long* dims = data->dims_ksp; ifft(DIMS, dims, FFT_FLAGS, dst, src); // FIXME fftmod is slow #if 0 fftscale(DIMS, dims, FFT_FLAGS, dst, dst); ifftmod(DIMS, dims, FFT_FLAGS, dst, dst); #else md_zmulc2(DIMS, dims, data->strs_ksp, dst, data->strs_ksp, dst, data->strs_pat, data->fftmod_mat); #endif operator_p_apply(data->thresh, mu, DIMS, dims, dst, DIMS, dims, dst); #if 0 fftmod(DIMS, dims, FFT_FLAGS, dst, dst); fftscale(DIMS, dims, FFT_FLAGS, dst, dst); #else md_zmul2(DIMS, dims, data->strs_ksp, dst, data->strs_ksp, dst, data->strs_pat, data->fftmod_mat); #endif fft(DIMS, dims, FFT_FLAGS, dst, dst); } static void data_consistency_proj_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { UNUSED(mu); const auto data = CAST_DOWN(data, _data); if (-1. != data->lambda) robust_consistency(data->lambda, data->dims_ksp, dst, data->pattern, data->kspace); else data_consistency(data->dims_ksp, dst, data->pattern, data->kspace, src); } static void sense_proj_apply(const operator_data_t* _data, float mu, complex float* dst, const complex float* src) { UNUSED(mu); const auto data = CAST_DOWN(data, _data); // assumes normalized sensitivities linop_adjoint_unchecked(data->sense_op, data->tmp, src); linop_forward_unchecked(data->sense_op, dst, data->tmp); } static void proj_del(const operator_data_t* _data) { UNUSED(_data); } static float compute_norm(const void* _data, const float* ksp) { const struct data* data = _data; // FIXME: CAST? float norm = md_znorm(DIMS, data->dims_ksp, (complex float*)ksp); //assert(isnormal(norm)); return norm; } void pocs_recon(const long dims[DIMS], const struct operator_p_s* thresh, int maxiter, float alpha, float lambda, complex float* result, const complex float* maps, const complex float* pattern, const complex float* kspace) { struct iter_pocs_conf pconf = iter_pocs_defaults; pconf.maxiter = maxiter; pocs_recon2(iter2_pocs, &pconf, NULL, dims, thresh, alpha, lambda, result, maps, pattern, kspace); } void pocs_recon2(italgo_fun2_t italgo, void* iconf, const struct linop_s* ops[3], const long dims[DIMS], const struct operator_p_s* thresh_op, float alpha, float lambda, complex float* result, const complex float* maps, const complex float* pattern, const complex float* kspace) { long dims_pat[DIMS]; long dims_img[DIMS]; long dims_ksp[DIMS]; md_select_dims(DIMS, ~(COIL_FLAG | MAPS_FLAG), dims_pat, dims); md_select_dims(DIMS, ~(MAPS_FLAG), dims_ksp, dims); md_select_dims(DIMS, ~(COIL_FLAG), dims_img, dims); long strs_pat[DIMS]; long strs_ksp[DIMS]; md_calc_strides(DIMS, strs_pat, dims_pat, CFL_SIZE); md_calc_strides(DIMS, strs_ksp, dims_ksp, CFL_SIZE); struct data data; SET_TYPEID(data, &data); data.pattern = pattern; data.kspace = kspace; data.lambda = lambda; data.alpha = alpha; md_copy_dims(DIMS, data.dims_ksp, dims_ksp); md_copy_dims(DIMS, data.dims_pat, dims_pat); md_copy_strides(DIMS, data.strs_ksp, strs_ksp); md_copy_strides(DIMS, data.strs_pat, strs_pat); data.sense_op = sense_init(dims, FFT_FLAGS|MAPS_FLAG|COIL_FLAG, maps); data.thresh = thresh_op; data.tmp = md_alloc_sameplace(DIMS, dims_img, CFL_SIZE, kspace); complex float* fftmod_mat = md_alloc_sameplace(DIMS, dims_pat, CFL_SIZE, kspace); complex float one[1] = { 1. }; md_fill(DIMS, dims_pat, fftmod_mat, one, CFL_SIZE ); fftscale(DIMS, dims_pat, FFT_FLAGS, fftmod_mat, fftmod_mat); fftmod(DIMS, dims_pat, FFT_FLAGS, fftmod_mat, fftmod_mat); data.fftmod_mat = fftmod_mat; const struct operator_p_s* sense_proj = operator_p_create(DIMS, dims_ksp, DIMS, dims_ksp, CAST_UP(&data), sense_proj_apply, proj_del); const struct operator_p_s* data_consistency_proj = operator_p_create(DIMS, dims_ksp, DIMS, dims_ksp, CAST_UP(&data), data_consistency_proj_apply, proj_del); const struct operator_p_s* sparsity_proj = NULL; if (NULL != thresh_op) sparsity_proj = operator_p_create(DIMS, dims_ksp, DIMS, dims_ksp, CAST_UP(&data), sparsity_proj_apply, proj_del); else sparsity_proj = prox_leastsquares_create(DIMS, dims_ksp, alpha, NULL); const struct operator_p_s* prox_ops[3] = { data_consistency_proj, sense_proj, sparsity_proj }; //const struct operator_p_s* prox_ops[3] = { data_consistency_proj, sense_proj, thresh_op }; const struct operator_p_s* xupdate_op = operator_p_create(DIMS, dims_ksp, DIMS, dims_ksp, CAST_UP(&data), xupdate_apply, proj_del); long size = 2 * md_calc_size(DIMS, dims_ksp); md_clear(DIMS, dims_ksp, result, CFL_SIZE); struct iter_monitor_s* mon = create_monitor(size, NULL, (void*)&data, compute_norm); italgo(iconf, NULL, (alpha == 0.) ? 2 : 3, prox_ops, ops, NULL, xupdate_op, size, (float*)result, NULL, mon); free(mon); // FIXME debug_printf(DP_INFO, "Done\n"); md_free(data.tmp); md_free(fftmod_mat); linop_free(data.sense_op); operator_p_free(sense_proj); operator_p_free(data_consistency_proj); operator_p_free(sparsity_proj); operator_p_free(xupdate_op); } #ifdef USE_CUDA void pocs_recon_gpu(const long dims[DIMS], const struct operator_p_s* thresh, int maxiter, float alpha, float lambda, complex float* result, const complex float* maps, const complex float* pattern, const complex float* kspace) { struct iter_pocs_conf pconf = iter_pocs_defaults; pconf.maxiter = maxiter; pocs_recon_gpu2(iter2_pocs, &pconf, NULL, dims, thresh, alpha, lambda, result, maps, pattern, kspace); } void pocs_recon_gpu2(italgo_fun2_t italgo, void* iconf, const struct linop_s** ops, const long dims[DIMS], const struct operator_p_s* thresh, float alpha, float lambda, complex float* result, const complex float* maps, const complex float* pattern, const complex float* kspace) { long dims_pat[DIMS]; long dims_ksp[DIMS]; md_select_dims(DIMS, ~(COIL_FLAG | MAPS_FLAG), dims_pat, dims); md_select_dims(DIMS, ~MAPS_FLAG, dims_ksp, dims); complex float* gpu_maps = md_gpu_move(DIMS, dims, maps, CFL_SIZE); complex float* gpu_pat = md_gpu_move(DIMS, dims_pat, pattern, CFL_SIZE); complex float* gpu_ksp = md_gpu_move(DIMS, dims_ksp, kspace, CFL_SIZE); complex float* gpu_result = md_gpu_move(DIMS, dims_ksp, result, CFL_SIZE); pocs_recon2(italgo, iconf, ops, dims, thresh, alpha, lambda, gpu_result, gpu_maps, gpu_pat, gpu_ksp); md_copy(DIMS, dims_ksp, result, gpu_result, CFL_SIZE); md_free(gpu_result); md_free(gpu_pat); md_free(gpu_ksp); md_free(gpu_maps); } #endif bart-0.5.00/src/sense/pocs.h000066400000000000000000000026441353046746100155640ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include "misc/mri.h" #include "iter/iter2.h" #ifdef __cplusplus extern "C" { #endif struct operator_p_s; struct linop_s; extern void pocs_recon(const long dims[DIMS], const struct operator_p_s* thresh_data, int maxiter, float alpha, float lambda, _Complex float* result, const _Complex float* maps, const _Complex float* pattern, const _Complex float* kspace); extern void pocs_recon2(italgo_fun2_t italgo, void* iconf, const struct linop_s** ops, const long dims[DIMS], const struct operator_p_s* thresh_data, float alpha, float lambda, _Complex float* result, const _Complex float* maps, const _Complex float* pattern, const _Complex float* kspace); #ifdef USE_CUDA extern void pocs_recon_gpu(const long dims[DIMS], const struct operator_p_s* thresh, int maxiter, float alpha, float lambda, _Complex float* result, const _Complex float* maps, const _Complex float* pattern, const _Complex float* kspace); extern void pocs_recon_gpu2(italgo_fun2_t italgo, void* iconf, const struct linop_s** ops, const long dims[DIMS], const struct operator_p_s* thresh, float alpha, float lambda, _Complex float* result, const _Complex float* maps, const _Complex float* pattern, const _Complex float* kspace); #endif #ifdef __cplusplus } #endif bart-0.5.00/src/sense/recon.c000066400000000000000000000116371353046746100157230ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2016 Martin Uecker * 2013-2014 Jonathan Tamir * 2014 Frank Ong * * * Ra JB, Rim CY. Fast imaging using subencoding data sets from multiple * detectors. Magn Reson Med 1993; 30:142-145. * * Pruessmann KP, Weiger M, Scheidegger MB, Boesiger P. SENSE: Sensitivity * encoding for fast MRI. Magn Reson Med 1999; 42:952-962. * * Pruessmann KP, Weiger M, Boernert P, Boesiger P. Advances in sensitivity * encoding with arbitrary k-space trajectories. * Magn Reson Med 2001; 46:638-651. * * Uecker M, Lai P, Murphy MJ, Virtue P, Elad M, Pauly JM, Vasanawala SS, * Lustig M. ESPIRiT - An Eigenvalue Approach to Autocalibrating Parallel MRI: * Where SENSE meets GRAPPA. Magn Reson Med 2014; 71:990-1001. * */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "linops/linop.h" #include "linops/sampling.h" #include "linops/someops.h" #include "linops/realval.h" #include "iter/iter.h" #include "iter/lsqr.h" #include "iter/lad.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/mri.h" #include "sense/model.h" #include "recon.h" const struct sense_conf sense_defaults = { .rvc = false, .gpu = false, .rwiter = 1, .gamma = -1., .cclambda = 0., .bpsense = false, }; void debug_print_sense_conf(int level, const struct sense_conf* conf) { debug_printf(level, "sense conf:\n"); debug_printf(level, "\trvc: %s\n", conf->rvc ? "on" : "off"); debug_printf(level, "\trwiter: %d\n", conf->rwiter); debug_printf(level, "\tgamma: %f\n", conf->gamma); debug_printf(level, "\tcclambda: %f\n", conf->cclambda); debug_printf(level, "\n\n"); } // copied from flpmath.c (for md_sqrt below ) static void real_from_complex_dims(unsigned int D, long odims[D + 1], const long idims[D]) { odims[0] = 2; md_copy_dims(D, odims + 1, idims); } const struct operator_p_s* sense_recon_create(const struct sense_conf* conf, const long dims[DIMS], const struct linop_s* sense_op, const long pat_dims[DIMS], const complex float* pattern, italgo_fun2_t italgo, iter_conf* iconf, const complex float* init, unsigned int num_funs, const struct operator_p_s* thresh_op[num_funs], const struct linop_s* thresh_funs[num_funs], const struct operator_s* precond_op, struct iter_monitor_s* monitor) { struct lsqr_conf lsqr_conf = { conf->cclambda, conf->gpu }; const struct operator_p_s* op = NULL; assert(DIMS == linop_domain(sense_op)->N); long img_dims[DIMS]; md_copy_dims(DIMS, img_dims, linop_domain(sense_op)->dims); long ksp_dims[DIMS]; md_copy_dims(DIMS, ksp_dims, linop_codomain(sense_op)->dims); if (conf->rvc) { assert(!conf->bpsense); // FIXME: add rvc as separate constraint or build into forward model earlier struct linop_s* rvc = linop_realval_create(DIMS, img_dims); struct linop_s* tmp_op = linop_chain(rvc, sense_op); linop_free(rvc); linop_free(sense_op); sense_op = tmp_op; } if (1 < conf->rwiter) { assert(!conf->bpsense); // not compatible struct linop_s* sampling = linop_sampling_create(dims, pat_dims, pattern); struct linop_s* tmp_op = linop_chain(sense_op, sampling); linop_free(sampling); linop_free(sense_op); sense_op = tmp_op; unsigned int flags = 0; for (unsigned int i = 0; i < DIMS; i++) if (pat_dims[i] > 1) flags = MD_SET(flags, i); const struct lad_conf lad_conf = { conf->rwiter, conf->gamma, flags, &lsqr_conf }; op = lad2_create(&lad_conf, italgo, iconf, (const float*)init, sense_op, num_funs, thresh_op, thresh_funs); linop_free(sense_op); } else if (NULL == pattern) { if (conf->bpsense) op = lsqr2_create(&lsqr_conf, italgo, iconf, (const float*)init, NULL, NULL, num_funs, thresh_op, thresh_funs, monitor); else op = lsqr2_create(&lsqr_conf, italgo, iconf, (const float*)init, sense_op, precond_op, num_funs, thresh_op, thresh_funs, monitor); linop_free(sense_op); } else { assert(!conf->bpsense); // pattern should be built into forward model complex float* weights = md_alloc(DIMS, pat_dims, CFL_SIZE); #if 0 // buggy // md_zsqrt(DIMS, pat_dims, weights, pattern); #else long dimsR[DIMS + 1]; real_from_complex_dims(DIMS, dimsR, pat_dims); md_sqrt(DIMS + 1, dimsR, (float*)weights, (const float*)pattern); #endif struct linop_s* weights_op = linop_cdiag_create(DIMS, ksp_dims, ~COIL_FLAG, weights); md_free(weights); op = wlsqr2_create(&lsqr_conf, italgo, iconf, (const float*)init, sense_op, weights_op, precond_op, num_funs, thresh_op, thresh_funs, monitor); } return op; } bart-0.5.00/src/sense/recon.h000066400000000000000000000024251353046746100157230ustar00rootroot00000000000000/* Copyright 2013-2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #ifndef __SENSE_H #define __SENSE_H 1 #include "misc/mri.h" #include "iter/iter.h" #include "iter/iter2.h" #include "misc/cppwrap.h" /** * configuration parameters for sense reconstruction * * @param rvc TRUE for real-values constraints */ struct sense_conf { _Bool rvc; _Bool gpu; int rwiter; // should be moved into a recon_lad float gamma; // .. float cclambda; bool bpsense; }; extern const struct sense_conf sense_defaults; struct operator_s; struct operator_p_s; extern const struct operator_p_s* sense_recon_create(const struct sense_conf* conf, const long dims[DIMS], const struct linop_s* sense_op, const long pat_dims[DIMS], const complex float* pattern, italgo_fun2_t italgo, iter_conf* iconf, const complex float* init, unsigned int num_funs, const struct operator_p_s* thresh_op[num_funs], const struct linop_s* thresh_funs[num_funs], const struct operator_s* precond_op, struct iter_monitor_s* monitor); extern void debug_print_sense_conf(int debug_level, const struct sense_conf* conf); #include "misc/cppwrap.h" #endif bart-0.5.00/src/show.c000066400000000000000000000046731353046746100144620ustar00rootroot00000000000000/* Copyright 2013-2016. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013, 2015-2016 Martin Uecker * 2015-2016 Jon Tamir */ #define _GNU_SOURCE #include #include #include #include #include "num/multind.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = ""; static const char help_str[] = "Outputs values or meta data."; static void print_cfl(unsigned int N, const long dims[N], const complex float* data, const char* fmt, const char* sep) { // find first non-trivial dimension unsigned int l = 0; while ((l < N - 1) && (1 == dims[l])) l++; long T = md_calc_size(N, dims); const char* allowed_fmts[] = { "%+e%+ei", "%+f%+fi", }; for (unsigned int i = 0; i < ARRAY_SIZE(allowed_fmts); i++) if (0 == strcmp(allowed_fmts[i], fmt)) goto ok; debug_printf(DP_ERROR, "Invalid format string.\n"); return; ok: for (long i = 0; i < T; i++) { printf(fmt, crealf(data[i]), cimagf(data[i])); printf("%s", (0 == (i + 1) % dims[l]) ? "\n" : sep); } } int main_show(int argc, char* argv[]) { bool meta = false; int showdim = -1; const char* sep = strdup("\t"); const char* fmt = strdup("%+e%+ei"); const struct opt_s opts[] = { OPT_SET('m', &meta, "show meta data"), OPT_INT('d', &showdim, "dim", "show size of dimension"), OPT_STRING('s', &sep, "sep", "use as the separator"), OPT_STRING('f', &fmt, "format", "use as the format. Default: \"\%+e\%+ei\""), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); unsigned int N = DIMS; long dims[N]; complex float* data = load_cfl(argv[1], N, dims); if (-1 != showdim) { assert((showdim >= 0) && (showdim < (int)N)); bart_printf("%ld\n", dims[showdim]); goto out; } if (meta) { bart_printf("Type: complex float\n"); bart_printf("Dimensions: %d\n", N); // FIXME always DIMS bart_printf("AoD:"); for (unsigned int i = 0; i < N; i++) bart_printf("\t%ld", dims[i]); bart_printf("\n"); goto out; } print_cfl(N, dims, data, fmt, sep); out: unmap_cfl(N, dims, data); xfree(sep); xfree(fmt); return 0; } bart-0.5.00/src/simu/000077500000000000000000000000001353046746100143015ustar00rootroot00000000000000bart-0.5.00/src/simu/biot_savart.c000066400000000000000000000032521353046746100167640ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2017 Martin Uecker * * Biot-Savart law. * */ #include #include #include "misc/misc.h" #include "num/vec3.h" #include "biot_savart.h" typedef float vec3_t[3]; void biot_savart(vec3_t b, const vec3_t r, unsigned int N, const vec3_t curve[static N]) { double c = 1. / (4. * M_PI); /* mu_o */ vec3_clear(b); for (unsigned int i = 0; i < N; i++) { vec3_t l; vec3_sub(l, curve[(i + 1) % N], curve[i]); vec3_t d; vec3_sub(d, r, curve[i]); double n = vec3_norm(d); if (0. == n) continue; vec3_t x; vec3_rot(x, l, d); vec3_smul(x, x, c / pow(n, 3.)); //saxpy vec3_add(b, b, x); } } void vec3_ring(unsigned int N, vec3_t ring[N], const vec3_t c, const vec3_t n, float r) { assert(1.E-7 > fabsf(1.f - vec3_norm(n))); // compute vec orth to n vec3_t b1 = { 1., 1., 1. }; int d = 0; for (unsigned int i = 0; i < 3; i++) if (fabsf(n[d]) < fabsf(n[i])) d = i; b1[d] = -(n[0] + n[1] + n[2] - n[d]) / n[d]; vec3_smul(b1, b1, 1. / vec3_norm(b1)); assert(1.E-6 > fabsf(1.f - vec3_norm(b1))); assert(1.E-6 > fabsf(vec3_sdot(n, b1))); vec3_t b2; vec3_rot(b2, b1, n); assert(1.E-6 > fabsf(1.f - vec3_norm(b2))); assert(1.E-6 > fabsf(vec3_sdot(n, b2))); assert(1.E-6 > fabsf(vec3_sdot(b1, b2))); for (unsigned int i = 0; i < N; i++) { float x = sinf(2. * M_PI * i / N); float y = cosf(2. * M_PI * i / N); vec3_copy(ring[i], c); vec3_saxpy(ring[i], ring[i], r * x, b1); vec3_saxpy(ring[i], ring[i], r * y, b2); } } bart-0.5.00/src/simu/biot_savart.h000066400000000000000000000003361353046746100167710ustar00rootroot00000000000000 typedef float vec3_t[3]; extern void biot_savart(vec3_t x, const vec3_t r, unsigned int N, const vec3_t curve[static N]); extern void vec3_ring(unsigned int N, vec3_t ring[N], const vec3_t c, const vec3_t n, float r); bart-0.5.00/src/simu/bloch.c000066400000000000000000000037741353046746100155470ustar00rootroot00000000000000 #include #include #include "num/vec3.h" #include "bloch.h" void bloch_ode(float out[3], const float in[3], float r1, float r2, const float gb[3]) { float m0 = 1.; vec3_rot(out, in, gb); out[0] -= in[0] * r2; out[1] -= in[1] * r2; out[2] -= (in[2] - m0) * r1; } void bloch_pdy(float out[3][3], const float in[3], float r1, float r2, const float gb[3]) { (void)in; vec3_rot(out[0], (float[3]){ 1., 0., 0. }, gb); out[0][0] -= r2; vec3_rot(out[1], (float[3]){ 0., 1., 0. }, gb); out[1][1] -= r2; vec3_rot(out[2], (float[3]){ 0., 0., 1. }, gb); out[2][2] -= r1; } void bloch_pdp(float out[2][3], const float in[3], float r1, float r2, const float gb[3]) { (void)r1; (void)r2; (void)gb; float m0 = 1.; out[0][0] = 0.; out[0][1] = 0.; out[0][2] = -(in[2] - m0); out[1][0] = -in[0]; out[1][1] = -in[1]; out[1][2] = 0.; } void bloch_relaxation(float out[3], float t, const float in[3], float r1, float r2, const float gb[3]) { float m0 = 1.; assert((0. == gb[0]) && (0. == gb[1])); // no B1(t) out[0] = (in[0] * cosf(gb[2] * t) - in[1] * sinf(gb[2] * t)) * expf(-t * r2); out[1] = -(in[0] * sinf(gb[2] * t) + in[1] * cosf(gb[2] * t)) * expf(-t * r2); out[2] = in[2] + (m0 - in[2]) * (1. - expf(-t * r1)); } void bloch_excitation(float out[3], float t, const float in[3], float r1, float r2, const float gb[3]) { (void)r1; (void)r2; assert(0. == gb[2]); // no gradient, rotating frame out[0] = in[0]; out[1] = (in[2] * sinf(gb[0] * t) + in[0] * cosf(gb[0] * t)); out[2] = (in[2] * cosf(gb[0] * t) - in[0] * sinf(gb[0] * t)); } static void matf_copy(int N, int M, float out[N][M], /*const*/ float in[N][M]) { for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) out[i][j] = in[i][j]; } void bloch_matrix_ode(float matrix[4][4], float r1, float r2, const float gb[3]) { float m0 = 1.; float m[4][4] = { { -r2, gb[2], -gb[1], 0. }, { -gb[2], -r2, gb[0], 0. }, { gb[1], -gb[0], -r1, m0 * r1 }, { 0., 0., 0., 0. }, }; matf_copy(4, 4, matrix, m); } bart-0.5.00/src/simu/bloch.h000066400000000000000000000014321353046746100155410ustar00rootroot00000000000000 // rad s^-1 T^-1 #define GAMMA_H1 267.513e6 // @3T #define WATER_T1 3.0 #define WATER_T2 0.3 #define SKYRA_B0 3. // T/m #define SKYRA_GRADIENT 0.045 // T/m/s #define SKYRA_RAMP 200. extern void bloch_ode(float out[3], const float in[3], float r1, float r2, const float gb[3]); extern void bloch_relaxation(float out[3], float t, const float in[3], float r1, float r2, const float gb[3]); extern void bloch_excitation(float out[3], float t, const float in[3], float r1, float r2, const float gb[3]); extern void bloch_matrix_ode(float matrix[4][4], float r1, float r2, const float gb[3]); extern void bloch_pdy(float out[3][3], const float in[3], float r1, float r2, const float gb[3]); extern void bloch_pdp(float out[2][3], const float in[3], float r1, float r2, const float gb[3]); bart-0.5.00/src/simu/coil.c000066400000000000000000000016141353046746100153750ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2017 Martin Uecker * * Simple coil using Biot-Savart law. * */ #include #include #include #include "misc/misc.h" #include "simu/biot_savart.h" #include "coil.h" const struct coil coil_defaults = { .size = 0.2, .dist = 1.5, }; complex float coil(const struct coil* data, float x[3], unsigned int N, unsigned int i) { assert(i < N); float dist = data->dist; vec3_t c[50]; vec3_t nc1 = { dist * sinf(2. * M_PI * i / N), dist * cosf(2. * M_PI * i / N), 0. }; vec3_t nc2 = { sinf(2. * M_PI * i / N), cosf(2. * M_PI * i / N), 0. }; vec3_ring(50, c, nc1, nc2, data->size); vec3_t b; biot_savart(b, x, 50, (const vec3_t*)c); return b[0] + 1.i * b[1]; } bart-0.5.00/src/simu/coil.h000066400000000000000000000002701353046746100153770ustar00rootroot00000000000000 struct coil { float size; float dist; }; extern const struct coil coil_defaults; extern complex float coil(const struct coil* data, float x[3], unsigned int N, unsigned int i); bart-0.5.00/src/simu/phantom.c000066400000000000000000000227261353046746100161240ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2012-2017 Martin Uecker * * Simple numerical phantom which simulates image-domain or * k-space data with multiple channels. * */ #include #include #include #include #include #include "num/multind.h" #include "num/loop.h" #include "num/flpmath.h" #include "misc/misc.h" #include "misc/mri.h" #include "simu/shepplogan.h" #include "simu/sens.h" #include "simu/coil.h" #include "phantom.h" #define MAX_COILS 8 #define COIL_COEFF 5 typedef complex float (*krn_t)(void* _data, const double mpos[3]); static complex float xsens(unsigned int c, double mpos[3], void* data, krn_t fun) { assert(c < MAX_COILS); #if 1 complex float val = 0.; long sh = (COIL_COEFF - 1) / 2; for (int i = 0; i < COIL_COEFF; i++) for (int j = 0; j < COIL_COEFF; j++) val += sens_coeff[c][i][j] * cexpf(-2.i * M_PI * ((i - sh) * mpos[0] + (j - sh) * mpos[1]) / 4.); #else float p[3] = { mpos[0], mpos[1], mpos[2] }; complex float val = coil(&coil_defaults, p, MAX_COILS, c); #endif return val * fun(data, mpos); } /* * To simulate channels, we simply convolve with a few Fourier coefficients * of the sensitivities. See: * * M Guerquin-Kern, L Lejeune, KP Pruessmann, and M Unser, * Realistic Analytical Phantoms for Parallel Magnetic Resonance Imaging * IEEE TMI 31:626-636 (2012) */ static complex float ksens(unsigned int c, double mpos[3], void* data, krn_t fun) { assert(c < MAX_COILS); complex float val = 0.; for (int i = 0; i < COIL_COEFF; i++) { for (int j = 0; j < COIL_COEFF; j++) { long sh = (COIL_COEFF - 1) / 2; double mpos2[3] = { mpos[0] + (double)(i - sh) / 4., mpos[1] + (double)(j - sh) / 4., mpos[2] }; val += sens_coeff[c][i][j] * fun(data, mpos2); } } return val; } static complex float nosens(unsigned int c, double mpos[3], void* data, krn_t fun) { UNUSED(c); return fun(data, mpos); } struct data1 { bool sens; const long dims[3]; void* data; krn_t fun; }; static complex float xkernel(void* _data, const long pos[]) { struct data1* data = _data; double mpos[3] = { (double)(pos[0] - data->dims[0] / 2) / (0.5 * (double)data->dims[0]), (double)(pos[1] - data->dims[1] / 2) / (0.5 * (double)data->dims[1]), (double)(pos[2] - data->dims[2] / 2) / (0.5 * (double)data->dims[2]) }; return (data->sens ? xsens : nosens)(pos[COIL_DIM], mpos, data->data, data->fun); } static complex float kkernel(void* _data, const long pos[]) { struct data1* data = _data; double mpos[3] = { (double)(pos[0] - data->dims[0] / 2) / 2., (double)(pos[1] - data->dims[1] / 2) / 2., (double)(pos[2] - data->dims[2] / 2) / 2. }; return (data->sens ? ksens : nosens)(pos[COIL_DIM], mpos, data->data, data->fun); } struct data2 { const complex float* traj; long istrs[DIMS]; bool sens; void* data; krn_t fun; }; static complex float nkernel(void* _data, const long pos[]) { struct data2* data = _data; double mpos[3]; mpos[0] = data->traj[md_calc_offset(3, data->istrs, pos) + 0] / 2.; mpos[1] = data->traj[md_calc_offset(3, data->istrs, pos) + 1] / 2.; mpos[2] = data->traj[md_calc_offset(3, data->istrs, pos) + 2] / 2.; return (data->sens ? ksens : nosens)(pos[COIL_DIM], mpos, data->data, data->fun); } struct krn_data { bool kspace; unsigned int N; const struct ellipsis_s* el; }; static complex float krn(void* _data, const double mpos[3]) { struct krn_data* data = _data; return phantom(data->N, data->el, mpos, data->kspace); } static complex float krnX(void* _data, const double mpos[3]) { struct krn_data* data = _data; return phantomX(data->N, data->el, mpos, data->kspace); } struct krn3d_data { bool kspace; unsigned int N; const struct ellipsis3d_s* el; }; static complex float krn3d(void* _data, const double mpos[3]) { struct krn3d_data* data = _data; return phantom3d(data->N, data->el, mpos, data->kspace); } static void sample(unsigned int N, const long dims[N], complex float* out, unsigned int D, const struct ellipsis_s* el, bool kspace, bool round) { struct data1 data = { .sens = (dims[COIL_DIM] > 1), .dims = { dims[0], dims[1], dims[2] }, .data = &(struct krn_data){ kspace, D, el }, .fun = round ? krn : krnX, }; md_parallel_zsample(N, dims, out, &data, kspace ? kkernel : xkernel); } void calc_phantom(const long dims[DIMS], complex float* out, bool kspace) { sample(DIMS, dims, out, 10, shepplogan_mod, kspace, 1); } void calc_geo_phantom(const long dims[DIMS], complex float* out, bool kspace, int phtype) { complex float* round = md_alloc(DIMS, dims, CFL_SIZE); complex float* angular = md_alloc(DIMS, dims, CFL_SIZE); switch (phtype) { case 1: sample(DIMS, dims, round, ARRAY_SIZE(phantom_geo1), phantom_geo1, kspace, true); sample(DIMS, dims, angular, ARRAY_SIZE(phantom_geo2), phantom_geo2, kspace, false); md_zadd(DIMS, dims, out, round, angular); break; case 2: sample(DIMS, dims, round, ARRAY_SIZE(phantom_geo4), phantom_geo4, kspace, true); sample(DIMS, dims, angular, ARRAY_SIZE(phantom_geo3), phantom_geo3, kspace, false); md_zadd(DIMS, dims, out, round, angular); break; default: assert(0); } md_free(round); md_free(angular); } static void sample3d(unsigned int N, const long dims[N], complex float* out, unsigned int D, const struct ellipsis3d_s* el, bool kspace) { struct data1 data = { .sens = (dims[COIL_DIM] > 1), .dims = { dims[0], dims[1], dims[2] }, .data = &(struct krn3d_data){ kspace, D, el }, .fun = krn3d, }; md_parallel_zsample(N, dims, out, &data, kspace ? kkernel : xkernel); } void calc_phantom3d(const long dims[DIMS], complex float* out, bool kspace) { sample3d(DIMS, dims, out, 10, shepplogan3d, kspace); } static void sample_noncart(const long dims[DIMS], complex float* out, const complex float* traj, unsigned int D, const struct ellipsis_s* el, bool round) { struct data2 data = { .traj = traj, .sens = (dims[COIL_DIM] > 1), .data = &(struct krn_data){ true, D, el }, .fun = round ? krn : krnX, }; assert(3 == dims[0]); long odims[DIMS]; md_select_dims(DIMS, 2 + 4 + 8, odims, dims); long sdims[DIMS]; md_select_dims(DIMS, 1 + 2 + 4, sdims, dims); md_calc_strides(DIMS, data.istrs, sdims, 1); md_parallel_zsample(DIMS, odims, out, &data, nkernel); } static void sample3d_noncart(const long dims[DIMS], complex float* out, const complex float* traj, unsigned int D, const struct ellipsis3d_s* el) { struct data2 data = { .traj = traj, .sens = (dims[COIL_DIM] > 1), .data = &(struct krn3d_data){ true, D, el }, .fun = krn3d, }; assert(3 == dims[0]); long odims[DIMS]; md_select_dims(DIMS, 2 + 4 + 8, odims, dims); long sdims[DIMS]; md_select_dims(DIMS, 1 + 2 + 4, sdims, dims); md_calc_strides(DIMS, data.istrs, sdims, 1); md_parallel_zsample(DIMS, odims, out, &data, nkernel); } void calc_phantom_noncart(const long dims[DIMS], complex float* out, const complex float* traj) { sample_noncart(dims, out, traj, 10, shepplogan_mod, 1); } void calc_geo_phantom_noncart(const long dims[DIMS], complex float* out, const complex float* traj, int phtype) { long kdims[DIMS]; md_select_dims(DIMS, ~READ_FLAG, kdims, dims); complex float* round = md_alloc(DIMS, kdims, CFL_SIZE); complex float* angular = md_alloc(DIMS, kdims, CFL_SIZE); switch (phtype) { case 1: sample_noncart(dims, round, traj, ARRAY_SIZE(phantom_geo1), phantom_geo1, true); sample_noncart(dims, angular, traj, ARRAY_SIZE(phantom_geo2), phantom_geo2, false); md_zadd(DIMS, kdims, out, round, angular); break; case 2: sample_noncart(dims, round, traj, ARRAY_SIZE(phantom_geo4), phantom_geo4, true); sample_noncart(dims, angular, traj, ARRAY_SIZE(phantom_geo3), phantom_geo3, false); md_zadd(DIMS, kdims, out, round, angular); break; default: assert(0); } md_free(round); md_free(angular); } void calc_phantom3d_noncart(const long dims[DIMS], complex float* out, const complex float* traj) { sample3d_noncart(dims, out, traj, 10, shepplogan3d); } static complex float cnst_one(void* _data, const double mpos[2]) { UNUSED(_data); UNUSED(mpos); return 1.; } void calc_sens(const long dims[DIMS], complex float* sens) { struct data1 data = { .sens = true, .dims = { dims[0], dims[1], dims[2] }, .data = NULL, .fun = cnst_one, }; md_parallel_zsample(DIMS, dims, sens, &data, xkernel); } void calc_circ(const long dims[DIMS], complex float* out, bool kspace) { sample(DIMS, dims, out, 1, phantom_disc, kspace, 1); } void calc_circ3d(const long dims[DIMS], complex float* out, bool kspace) { sample3d(DIMS, dims, out, 1, phantom_disc3d, kspace); } void calc_ring(const long dims[DIMS], complex float* out, bool kspace) { sample(DIMS, dims, out, 4, phantom_ring, kspace, 1); } void calc_moving_circ(const long dims[DIMS], complex float* out, bool kspace) { struct ellipsis_s disc[1] = { phantom_disc[0] }; disc[0].axis[0] /= 3; disc[0].axis[1] /= 3; long strs[DIMS]; md_calc_strides(DIMS, strs, dims, sizeof(complex float)); long dims1[DIMS]; md_select_dims(DIMS, ~MD_BIT(TE_DIM), dims1, dims); for (int i = 0; i < dims[TE_DIM]; i++) { disc[0].center[0] = 0.5 * sin(2. * M_PI * (float)i / (float)dims[TE_DIM]); disc[0].center[1] = 0.5 * cos(2. * M_PI * (float)i / (float)dims[TE_DIM]); sample(DIMS, dims1, (void*)out + strs[TE_DIM] * i, 1, disc, kspace, 1); } } bart-0.5.00/src/simu/phantom.h000066400000000000000000000017451353046746100161270ustar00rootroot00000000000000 #include "misc/mri.h" extern void calc_phantom(const long dims[DIMS], complex float* out, _Bool ksp); extern void calc_geo_phantom(const long dims[DIMS], complex float* out, _Bool ksp, int phtype); extern void calc_phantom_noncart(const long dims[3], complex float* out, const complex float* traj); extern void calc_geo_phantom_noncart(const long dims[3], complex float* out, const complex float* traj, int phtype); extern void calc_sens(const long dims[DIMS], complex float* sens); extern void calc_circ(const long dims[DIMS], complex float* img, _Bool ksp); extern void calc_ring(const long dims[DIMS], complex float* img, _Bool ksp); extern void calc_phantom3d(const long dims[DIMS], complex float* out, _Bool ksp); extern void calc_phantom3d_noncart(const long dims[3], complex float* out, const complex float* traj); extern void calc_circ3d(const long dims[DIMS], complex float* out, _Bool kspace); extern void calc_moving_circ(const long dims[DIMS], complex float* out, bool kspace); bart-0.5.00/src/simu/sens.c000066400000000000000000000144121353046746100154170ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2013 Martin Uecker */ #include #include "sens.h" const complex float sens_coeff[8][5][5] = { { // coil0 { +2.202641e+02+7.959795e+02i, +7.555631e+02-1.436550e+03i, +2.545977e+03+6.890254e+02i, -1.556657e+03+1.514510e+03i, +2.119276e+02-1.494780e+03i }, { +1.298826e+03-2.217249e+02i, +5.104937e+03-1.257278e+03i, +2.718070e+03+9.347223e+03i, -4.162577e+03+4.012845e+03i, -2.934868e+02-1.494939e+02i }, { -2.586698e+03+3.241368e+02i, +2.655842e+02-1.423245e+04i, +3.444878e+04-5.959087e-07i, +2.655845e+02+1.423245e+04i, -2.586697e+03-3.241368e+02i }, { -2.934868e+02+1.494939e+02i, -4.162577e+03-4.012845e+03i, +2.718070e+03-9.347224e+03i, +5.104937e+03+1.257278e+03i, +1.298826e+03+2.217249e+02i }, { +2.119276e+02+1.494780e+03i, -1.556657e+03-1.514511e+03i, +2.545977e+03-6.890254e+02i, +7.555631e+02+1.436550e+03i, +2.202641e+02-7.959794e+02i }, }, { // coil1 { -5.140192e+02+3.919716e+02i, +1.894585e+03-6.871808e+02i, -1.588401e+03-9.072462e+02i, +1.612868e+03+3.162505e+03i, -1.764654e+03-7.521263e+01i }, { +1.468621e+03+2.462891e+03i, +9.060663e+02-3.810722e+03i, +1.295797e+04+1.274518e+03i, +9.795861e+03+4.041410e+03i, +5.382768e+03+1.496270e+03i }, { +6.432245e+03-1.873246e+03i, -6.606911e+03+1.347433e+03i, +1.469823e+04-2.828712e+04i, +6.094570e+03-3.186246e+03i, +1.553516e+03-6.658626e+03i }, { +1.552164e+02-2.608411e+03i, -4.773840e+02+4.141277e+03i, -1.697275e+04-4.176371e+03i, +1.530776e+02-6.096529e+03i, -1.256617e+03-3.806721e+03i }, { +1.427317e+03-6.593576e+02i, +3.361672e+03+2.074898e+03i, -1.207303e+03+5.915274e+03i, -1.866361e+03+2.202192e+02i, -2.244576e+03+5.222404e+02i }, }, { // coil2 { +1.501215e+03+5.783638e+02i, -4.342622e+02-3.816680e+03i, +1.776472e+03+3.912266e+03i, +7.807321e+03-4.950209e+03i, -2.595354e+03-2.460056e+03i }, { +2.369316e+03-2.313158e+03i, +9.616589e+02-1.347896e+02i, +1.163739e+04-1.087814e+04i, +5.465111e+03-1.369369e+04i, -2.497076e+03-7.660470e+03i }, { -1.154424e+03-5.152002e+03i, +5.065459e+03+2.144815e+03i, -8.206305e+03-2.679990e+04i, -1.085187e+04-1.832581e+03i, -1.138738e+04+2.371703e+03i }, { -1.613378e+03+1.783068e+03i, +2.226849e+03-2.917332e+03i, -1.126524e+04+1.535570e+04i, -1.155414e+03+9.211537e+02i, +2.441054e+03+3.475593e+03i }, { +2.149000e+03-1.050538e+03i, +1.897796e+02-2.738874e+03i, +9.831870e+03+3.711983e+01i, +6.797585e+02+1.121489e+03i, +2.977299e+03-2.676358e+02i }, }, { // coil3 { +9.225188e+02-1.609105e+03i, +3.003085e+02-4.805967e+03i, +3.010118e+03-5.193128e+03i, -7.148681e+03-6.014095e+03i, -5.118819e+03+6.886482e+03i }, { -7.304860e+01-1.906521e+03i, +4.666944e+03-8.186537e+03i, -4.628897e+03-1.670177e+04i, -9.002204e+03-5.413904e+03i, -5.991946e+03+3.112899e+03i }, { -1.707291e+03+1.371777e+03i, +6.265779e+03-4.096543e+03i, -1.623247e+04-1.249279e+04i, -5.735404e+03+1.462694e+04i, +3.235129e+03+7.745793e+03i }, { +2.658034e+03-2.003479e+03i, -5.550209e+03-6.058204e+02i, +4.231377e+03+1.547026e+04i, +5.596798e+03-8.212248e+03i, -2.146848e+02-8.379209e+03i }, { +7.590588e+02-2.001688e+03i, +4.298658e+03-8.379312e+02i, +8.961587e+02-1.114809e+04i, -1.882075e+03+3.505513e+03i, -9.920860e+01-1.958216e+01i }, }, { // coil4 { +1.038110e+03+1.053870e+03i, +9.244695e+03+1.892697e+03i, -3.192582e+03-6.490971e+03i, -9.345550e+02-5.915621e+02i, -5.048445e+03-5.094557e+02i }, { +6.029613e+03+9.528574e+03i, +1.726803e+04+1.136792e+04i, +1.704588e+04-6.327428e+03i, -1.018518e+03-4.875073e+03i, -1.385726e+03-2.624488e+03i }, { -5.607942e+03+3.239110e+03i, -6.596133e+02+1.426120e+04i, +1.907908e+04+6.801775e+03i, -9.809665e+03-9.162689e+03i, +2.646640e+03+3.444627e+03i }, { +3.773911e+03-3.830415e+03i, -2.280376e+03-6.118903e+03i, -9.791950e+03-1.582865e+03i, +1.482043e+04+8.187234e+03i, +2.503851e+03-5.622277e+03i }, { -3.532414e+02+2.797883e+03i, +1.086923e+03+4.907002e+03i, +2.711129e+03-4.658596e+02i, -6.884295e+03+1.658655e+03i, +2.195509e+03+1.532364e+03i }, }, { // coil5 { -2.660406e+03+1.130288e+03i, -2.684663e+03-4.547482e+03i, -1.091036e+03+1.039176e+04i, +3.794462e+03-3.726057e+03i, -9.599513e+02+2.510410e+03i }, { +2.453693e+03-1.127183e+04i, +3.368645e+03-1.562005e+04i, -6.638387e+03-2.965991e+03i, +3.831320e+03+2.531652e+03i, -2.198729e+03-5.958389e+02i }, { +1.428178e+04+9.163301e+02i, +1.684055e+04-6.384269e+03i, +1.658437e+04-1.232798e+04i, -1.406222e+04+1.113432e+04i, +3.592359e+03-6.771321e+03i }, { -1.660563e+03+2.839105e+03i, -2.896235e+02+1.029472e+03i, -3.908763e+03+3.005041e+03i, +4.267630e+03-1.222684e+04i, +3.162250e+03+3.059668e+03i }, { +1.229621e+03+1.214108e+03i, +3.580651e+03+6.040717e+02i, +7.638826e+02+2.616962e+03i, +4.679096e+03+3.197829e+03i, -2.025938e+03+1.366729e+03i }, }, { // coil6 { +1.532993e+03+3.085543e+03i, +1.698160e+02-2.059932e+03i, +8.620593e+03+5.947357e+03i, -1.818730e+03-3.486291e+03i, +2.804918e+03+2.657346e+02i }, { -5.363040e+03-8.659919e+03i, -1.811624e+03-1.273996e+04i, +5.336066e+02+4.722509e+03i, +5.288265e+03-4.540653e+02i, -1.550763e+03+3.172655e+03i }, { +1.484031e+04-8.435797e+03i, +1.909462e+04-1.153338e+04i, +2.644743e+04+1.609464e+03i, -1.835121e+04+1.685986e+04i, -2.060884e+03-1.164399e+04i }, { +3.565514e+03+4.812732e+03i, -5.792477e+02-1.059542e+03i, -6.948085e+03+1.922669e+03i, -3.102303e+03-1.536498e+04i, +8.313277e+03-1.413219e+03i }, { +3.645370e+03+3.144318e+03i, +5.896468e+03-1.094847e+03i, +3.137289e+03+4.010566e+03i, +5.041110e+03-3.595689e+03i, +4.239519e+03+4.264271e+03i }, }, { // coil7 { +9.757094e+02-4.944947e+02i, -1.479025e+03-3.433955e+03i, +6.554174e+03-3.580007e+03i, -5.973520e+02+2.335976e+03i, -1.082375e+03-1.958220e+03i }, { -2.523083e+03+1.680365e+03i, -4.212411e+03-1.392797e+03i, +2.731082e+03+4.483586e+03i, -2.006126e+03-1.093595e+03i, +1.536401e+03-1.071117e+03i }, { -9.129410e+03-5.654936e+03i, -6.060043e+03-2.092658e+04i, +2.299950e+04-2.185407e+04i, +9.382429e+03+1.937377e+04i, -1.130825e+04+2.193837e+03i }, { +6.269709e+02-2.393860e+03i, -1.782260e+03-2.694656e+03i, +2.224400e+03-3.487669e+01i, -4.697312e+03+2.063353e+03i, -1.975369e+03-3.797778e+03i }, { +8.142875e+02-3.201539e+03i, +4.320247e+01-5.839946e+03i, +7.607719e+03-2.151906e+03i, -1.149005e+03+1.656691e+03i, -3.673436e+01-2.858548e+03i }, } }; bart-0.5.00/src/simu/sens.h000066400000000000000000000000631353046746100154210ustar00rootroot00000000000000 extern const complex float sens_coeff[8][5][5]; bart-0.5.00/src/simu/shepplogan.c000066400000000000000000000204611353046746100166100ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * 2013-2016 Martin Uecker */ #define _GNU_SOURCE #include #include #include #include #include "simu/shepplogan.h" #include "misc/misc.h" // AK Jain, 439. // modified Toft 199-200 multiply -0.98 -> 0.8 // multiply the rest by ten const struct ellipsis_s shepplogan[10] = { { 1., { .69, .92 }, { 0., 0. }, 0. }, { -.98, { .6624, .8740 }, { 0., -.0184 }, 0. }, { -.02, { .1100, .3100 }, { .22, 0. }, -18. / 360. * 2. * M_PI }, { -.02, { .1600, .4100 }, { -.22, 0 }, 18. / 360. * 2. * M_PI }, { .01, { .2100, .2500 }, { 0, .35 }, 0. }, { .01, { .0460, .0460 }, { 0, .1 }, 0. }, { .01, { .0460, .0460 }, { 0, -.1 }, 0. }, { .01, { .0460, .0230 }, { -.08, -.605 }, 0. }, { .01, { .0230, .0230 }, { 0, -.606 }, 0. }, { .01, { .0230, .0460 }, { .06, -.605 }, 0. } }; const struct ellipsis_s shepplogan_mod[10] = { { 1., { .69, .92 }, { 0., 0. }, 0. }, { -.8, { .6624, .8740 }, { 0., -.0184 }, 0. }, { -.2, { .1100, .3100 }, { .22, 0. }, -18. / 360. * 2. * M_PI }, { -.2, { .1600, .4100 }, { -.22, 0 }, 18. / 360. * 2. * M_PI }, { .1, { .2100, .2500 }, { 0, .35 }, 0 }, { .1, { .0460, .0460 }, { 0, .1 }, 0 }, { .1, { .0460, .0460 }, { 0, -.1 }, 0 }, { .1, { .0460, .0230 }, { -.08, -.605 }, 0 }, { .1, { .0230, .0230 }, { 0, -.606 }, 0 }, { .1, { .0230, .0460 }, { .06, -.605 }, 0 } }; const struct ellipsis_s phantom_disc[1] = { { 1., { 1., 1. }, { 0., 0. }, 0. } }; const struct ellipsis3d_s phantom_disc3d[1] = { { 1., { 1., 1., 1. }, { 0., 0., 0. }, 0. } }; // old: imaginary ring outside from 0.5 to 0.49 const struct ellipsis_s phantom_ring[4] = { { 1., { 0.75, 0.75 }, { 0., 0. }, 0. }, { -1. + 1.i, { 0.5, 0.5 }, { 0., 0. }, 0. }, { -1.i, { 0.48, 0.48 }, { 0., 0. }, 0. }, { 1., { 0.48, 0.48 }, { 0., 0. }, 0. }, // { 1., { 0.48, 0.48 }, { 0., 0. }, 0. }, }; // Some geometric objects const struct ellipsis_s phantom_geo1[3] = { { .5, { .2, .2 }, { .6, .5 }, 0 }, { .2, { .2, .4 }, { -.6, -.6 }, M_PI/7. }, { .6, { .3, .1 }, { .6, -.5 }, M_PI/5. }, }; const struct ellipsis_s phantom_geo2[2] = { { 0.5, { .5, -.5 }, { 0., 0. }, M_PI/5 }, { .7, { .2, .2 }, { -.5, .7 }, -M_PI/4 }, }; const struct ellipsis_s phantom_geo3[7] = { { 1., { .2, .2 }, { -.6, .6 }, M_PI/4 }, { 1., { .2, .2 }, { -.6, -.6 }, M_PI/4 }, { 0.6, { .07, .07 }, { 0.15, 0 }, 0. }, { 0.7, { .07, .07 }, { 0, 0 }, 0. }, { 0.8, { .07, .07 }, { -0.15, 0 }, 0. }, { 0.9, { .07, .07 }, { 0.15, 0.15}, 0. }, { 0.9, { .07, .07 }, { 0.15, -0.15}, 0. }, }; const struct ellipsis_s phantom_geo4[1] = { { 0.8, { .1, .7 }, { .6, 0 }, 0}, }; /* Magnetic Resonance in Medicine 58:430--436 (2007) * Three-Dimensional Analytical Magnetic Resonance * Imaging Phantom in the Fourier Domain * Cheng Guan Koay, Joelle E. Sarlls, and Evren Özarslan */ const struct ellipsis3d_s shepplogan3d[10] = { { 2., { .6900, .9200, .9000 }, { .000, .000, .000 }, 0. }, { -.8, { .6624, .8740, .8800 }, { .000, .000, .000 }, 0. }, { -.2, { .4100, .1600, .2100 }, { -.220, .000, -.250 }, 3. * M_PI / 5. }, { -.2, { .3100, .1100, .2200 }, { .220, .000, -.250 }, 2. * M_PI / 5. }, { .2, { .2100, .2500, .5000 }, { .000, .350, -.250 }, 0. }, { .2, { .0460, .0460, .0460 }, { .000, .100, -.250 }, 0. }, { .1, { .0460, .0230, .0200 }, { -.080, -.650, -.250 }, 0. }, { .1, { .0460, .0230, .0200 }, { .060, -.650, -.250 }, M_PI / 2. }, { .2, { .0560, .0400, .1000 }, { .060, -.105, .625 }, M_PI / 2. }, { -.2, { .0560, .0560, .1000 }, { .000, .100, .625 }, 0. } }; static double sinc(double x) { return (0. == x) ? 1. : (sin(x) / x); } static double jinc(double x) { return (0. == x) ? 1. : (2. * j1(x) / x); } static void rot2d(double x[2], const double in[2], double angle) { x[0] = cos(angle) * in[0] + sin(angle) * in[1]; x[1] = sin(angle) * in[0] - cos(angle) * in[1]; } complex double xellipsis(const double center[2], const double axis[2], double angle, const double p[2]) { double p90[2]; p90[0] = -p[1]; p90[1] = p[0]; double pshift[2]; pshift[0] = p90[0] + center[0]; pshift[1] = p90[1] + center[1]; double prot[2]; rot2d(prot, pshift, angle); double radius = pow(prot[0] / axis[0], 2.) + pow(prot[1] / axis[1], 2.); return (radius <= 1.) ? 1. : 0.; } complex double kellipsis(const double center[2], const double axis[2], double angle, const double p[2]) { double p90[2]; p90[0] = -p[1]; p90[1] = p[0]; double prot[2]; rot2d(prot, p90, angle); double radius = sqrt(pow(prot[0] * axis[0], 2.) + pow(prot[1] * axis[1], 2.)); complex double res = jinc(2. * M_PI * radius) * (axis[0] * axis[1]); return res * cexp(2.i * M_PI * (p90[0] * center[0] + p90[1] * center[1])) / sqrtf(2. * M_PI) * 2.; } complex double xrectangle(const double center[2], const double axis[2], double angle, const double p[2]) { double p90[2]; p90[0] = -p[1]; p90[1] = p[0]; double pshift[2]; pshift[0] = p90[0] + center[0]; pshift[1] = p90[1] + center[1]; double prot[2]; rot2d(prot, pshift, M_PI/4 + angle); double radius = fabs(prot[0] / axis[0] / sqrt(2)) + fabs(prot[1] / axis[1] / sqrt(2)); return (radius <= 1.) ? 1. : 0.; } complex double krectangle(const double center[2], const double axis[2], double angle, const double p[2]) { double p90[2]; p90[0] = -p[1]; p90[1] = p[0]; double prot[2]; rot2d(prot, p90, angle); complex double res = sinc(2. * M_PI * prot[0] * axis[0]) * sinc(2. * M_PI * prot[1] * axis[1]) * (axis[0] * axis[1]); return res * cexp(2.i * M_PI * (p90[0] * center[0] + p90[1] * center[1])) / sqrtf(2. * M_PI) * 2.; } complex double phantom(unsigned int N, const struct ellipsis_s arr[N], const double pos[3], bool ksp) { complex double res = 0.; for (unsigned int i = 0; i < N; i++) res += arr[i].intensity * (ksp ? kellipsis : xellipsis)(arr[i].center, arr[i].axis, arr[i].angle, pos); return res; } complex double phantomX(unsigned int N, const struct ellipsis_s arr[N], const double pos[2], bool ksp) { complex double res = 0.; for (unsigned int i = 0; i < N; i++) res += arr[i].intensity * (ksp ? krectangle : xrectangle)(arr[i].center, arr[i].axis, arr[i].angle, pos); return res; } static double ksphere3(double x) { return (0. == x) ? (1. / 3.) : ((sin(x) - x * cos(x)) / pow(x, 3.)); } complex double xellipsis3d(const double center[3], const double axis[3], double angle, const double p[3]) { double p90[3]; p90[0] = -p[1]; p90[1] = p[0]; p90[2] = p[2]; double pshift[3]; pshift[0] = p90[0] + center[0]; pshift[1] = p90[1] + center[1]; pshift[2] = p90[2] + center[2]; double prot[3]; rot2d(prot, pshift, angle); prot[2] = pshift[2]; double radius = pow(prot[0] / axis[0], 2.) + pow(prot[1] / axis[1], 2.) + pow(prot[2] / axis[2], 2.); return (radius <= 1.) ? 1. : 0.; } complex double kellipsis3d(const double center[3], const double axis[3], double angle, const double p[3]) { double p90[3]; p90[0] = -p[1]; p90[1] = p[0]; p90[2] = p[2]; double pshift[3]; pshift[0] = p90[0] + center[0]; pshift[1] = p90[1] + center[1]; pshift[2] = p90[2] + center[2]; double prot[3]; rot2d(prot, pshift, angle); prot[2] = pshift[2]; double radius = sqrt(pow(prot[0] * axis[0], 2.) + pow(prot[1] * axis[1], 2.) + pow(prot[2] * axis[2], 2.)); complex double res = ksphere3(2. * M_PI * radius) * (axis[0] * axis[1] * axis[2]); return res * cexp(2.i * M_PI * (p90[0] * center[0] + p90[1] * center[1] + p90[2] * center[2])) / sqrtf(M_PI) * sqrtf(8.); } complex double phantom3d(unsigned int N, const struct ellipsis3d_s arr[N], const double pos[3], bool ksp) { complex double res = 0.; for (unsigned int i = 0; i < N; i++) res += arr[i].intensity * (ksp ? kellipsis3d : xellipsis3d)(arr[i].center, arr[i].axis, arr[i].angle, pos); return res; } bart-0.5.00/src/simu/shepplogan.h000066400000000000000000000040151353046746100166120ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include "misc/cppwrap.h" struct ellipsis_s { complex double intensity; double axis[2]; double center[2]; double angle; }; struct ellipsis3d_s { complex double intensity; double axis[3]; double center[3]; double angle; }; extern const struct ellipsis_s shepplogan[10]; extern const struct ellipsis_s shepplogan_mod[10]; extern const struct ellipsis_s phantom_disc[1]; extern const struct ellipsis_s phantom_ring[4]; extern const struct ellipsis3d_s phantom_disc3d[1]; extern const struct ellipsis3d_s shepplogan3d[10]; extern const struct ellipsis_s phantom_geo1[3]; extern const struct ellipsis_s phantom_geo2[2]; extern const struct ellipsis_s phantom_geo3[7]; extern const struct ellipsis_s phantom_geo4[1]; extern complex double xellipsis(const double center[2], const double axis[2], double angle, const double p[2]); extern complex double kellipsis(const double center[2], const double axis[2], double angle, const double p[2]); extern complex double xellipsis3d(const double center[3], const double axis[3], double angle, const double p[3]); extern complex double kellipsis3d(const double center[3], const double axis[3], double angle, const double p[3]); extern complex double xrectangle(const double center[2], const double axis[2], double angle, const double p[2]); extern complex double krectangle(const double center[2], const double axis[2], double angle, const double p[2]); extern complex double phantom(unsigned int N, const struct ellipsis_s arr[__VLA(N)], const double pos[3], _Bool ksp); extern complex double phantomX(unsigned int N, const struct ellipsis_s arr[__VLA(N)], const double pos[3], _Bool ksp); extern complex double phantom3d(unsigned int N, const struct ellipsis3d_s arr[__VLA(N)], const double pos[3], _Bool ksp); #include "misc/cppwrap.h" bart-0.5.00/src/slice.c000066400000000000000000000032021353046746100145640ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "dim1 pos1 ... dimn posn "; static const char help_str[] = "Extracts a slice from positions along dimensions.\n"; int main_slice(int argc, char* argv[]) { const struct opt_s opts[] = {}; cmdline(&argc, argv, 4, 1000, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); int count = argc - 3; assert((count > 0) && (count % 2 == 0)); long in_dims[DIMS]; long out_dims[DIMS]; complex float* in_data = load_cfl(argv[argc - 2], DIMS, in_dims); md_copy_dims(DIMS, out_dims, in_dims); long pos2[DIMS] = { [0 ... DIMS - 1] = 0 }; unsigned long flags = 0L; for (int i = 0; i < count; i += 2) { unsigned int dim = atoi(argv[i + 1]); unsigned int pos = atoi(argv[i + 2]); assert(dim < DIMS); assert(pos < in_dims[dim]); out_dims[dim] = 1; flags = MD_SET(flags, dim); pos2[dim] = pos; } complex float* out_data = create_cfl(argv[argc - 1], DIMS, out_dims); md_slice(DIMS, flags, pos2, in_dims, out_data, in_data, CFL_SIZE); unmap_cfl(DIMS, out_dims, out_data); unmap_cfl(DIMS, in_dims, in_data); return 0; } bart-0.5.00/src/spow.c000066400000000000000000000022741353046746100144650ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "exponent "; static const char help_str[] = "Raise array to the power of {exponent}. The exponent can be a complex number.\n"; int main_spow(int argc, char* argv[argc]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); complex float expo; if (0 != parse_cfl(&expo, argv[1])) { fprintf(stderr, "ERROR: exponent %s is not a number.\n", argv[1]); return 1; } const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); md_zspow(N, dims, odata, idata, expo); unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/sqpics.c000066400000000000000000000445271353046746100150060ustar00rootroot00000000000000/* Copyright 2013-2015. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2015 Martin Uecker * 2014-2016 Frank Ong * 2014-2015 Jonathan Tamir * */ #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "num/ops.h" #include "num/iovec.h" #include "iter/prox.h" #include "iter/thresh.h" #include "iter/misc.h" #include "linops/linop.h" #include "linops/someops.h" #include "linops/grad.h" #include "linops/sum.h" #include "linops/sampling.h" #include "iter/iter.h" #include "iter/iter2.h" #include "noncart/nufft.h" //#include "sense/recon.h" #include "sense/model.h" #include "sense/optcom.h" #include "wavelet/wavthresh.h" #include "lowrank/lrthresh.h" #include "misc/debug.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #define NUM_REGS 10 static const char usage_str[] = " "; static const char help_str[] = "Parallel-imaging compressed-sensing reconstruction."; static void help_reg(void) { printf( "Generalized regularization options (experimental)\n\n" "-R :A:B:C\t is regularization type (single letter),\n" "\t\tA is transform flags, B is joint threshold flags,\n" "\t\tand C is regularization value. Specify any number\n" "\t\tof regularization terms.\n\n" "-R Q:C \tl2-norm in image domain\n" "-R I:B:C \tl1-norm in image domain\n" "-R W:A:B:C\tl1-wavelet\n" "-R T:A:B:C\ttotal variation\n" "-R T:7:0:.01\t3D isotropic total variation with 0.01 regularization.\n" "-R L:7:7:.02\tLocally low rank with spatial decimation and 0.02 regularization.\n" "-R M:7:7:.03\tMulti-scale low rank with spatial decimation and 0.03 regularization.\n" ); } static const struct linop_s* sense_nc_init(const long max_dims[DIMS], const long map_dims[DIMS], const complex float* maps, const long ksp_dims[DIMS], const long traj_dims[DIMS], const complex float* traj, struct nufft_conf_s conf, struct operator_s** precond_op) { long coilim_dims[DIMS]; long img_dims[DIMS]; md_select_dims(DIMS, ~MAPS_FLAG, coilim_dims, max_dims); md_select_dims(DIMS, ~COIL_FLAG, img_dims, max_dims); const struct linop_s* fft_op = nufft_create(DIMS, ksp_dims, coilim_dims, traj_dims, traj, NULL, conf); const struct linop_s* maps_op = maps2_create(coilim_dims, map_dims, img_dims, maps); //precond_op[0] = (struct operator_s*) nufft_precond_create( fft_op ); precond_op[0] = NULL; const struct linop_s* lop = linop_chain(maps_op, fft_op); linop_free(maps_op); linop_free(fft_op); return lop; } struct reg_s { enum { L1WAV, TV, LLR, MLR, IMAGL1, IMAGL2, L1IMG, L2IMG } xform; unsigned int xflags; unsigned int jflags; float lambda; }; enum algo_t { CG, IST, FISTA, ADMM }; struct opt_reg_s { float lambda; enum algo_t algo; struct reg_s regs[NUM_REGS]; unsigned int r; }; static bool opt_reg(void* ptr, char c, const char* optarg) { struct opt_reg_s* p = ptr; struct reg_s* regs = p->regs; const int r = p->r; const float lambda = p->lambda; assert(r < NUM_REGS); char rt[5]; switch (c) { case 'R': { // first get transform type int ret = sscanf(optarg, "%4[^:]", rt); assert(1 == ret); // next switch based on transform type if (strcmp(rt, "W") == 0) { regs[r].xform = L1WAV; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "L") == 0) { regs[r].xform = LLR; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); } else if (strcmp(rt, "M") == 0) { regs[r].xform = regs[0].xform; regs[r].xflags = regs[0].xflags; regs[r].jflags = regs[0].jflags; regs[r].lambda = regs[0].lambda; regs[0].xform = MLR; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[0].xflags, ®s[0].jflags, ®s[0].lambda); assert(3 == ret); } else if (strcmp(rt, "T") == 0) { regs[r].xform = TV; int ret = sscanf(optarg, "%*[^:]:%d:%d:%f", ®s[r].xflags, ®s[r].jflags, ®s[r].lambda); assert(3 == ret); p->algo = ADMM; } else if (strcmp(rt, "R1") == 0) { regs[r].xform = IMAGL1; int ret = sscanf(optarg, "%*[^:]:%d:%f", ®s[r].jflags, ®s[r].lambda); assert(2 == ret); regs[r].xflags = 0u; p->algo = ADMM; } else if (strcmp(rt, "R2") == 0) { regs[r].xform = IMAGL2; int ret = sscanf(optarg, "%*[^:]:%d:%f", ®s[r].jflags, ®s[r].lambda); assert(2 == ret); regs[r].xflags = 0u; p->algo = ADMM; } else if (strcmp(rt, "I") == 0) { regs[r].xform = L1IMG; int ret = sscanf(optarg, "%*[^:]:%d:%f", ®s[r].jflags, ®s[r].lambda); assert(2 == ret); regs[r].xflags = 0u; } else if (strcmp(rt, "Q") == 0) { regs[r].xform = L2IMG; int ret = sscanf(optarg, "%*[^:]:%f", ®s[r].lambda); assert(1 == ret); regs[r].xflags = 0u; regs[r].jflags = 0u; } else if (strcmp(rt, "h") == 0) { help_reg(); return 0; } else { error("Unrecognized regularization type: \"%s\" (-Rh for help).\n", rt); } p->r++; break; } case 'l': assert(r < NUM_REGS); regs[r].lambda = lambda; regs[r].xflags = 0u; regs[r].jflags = 0u; if (0 == strcmp("1", optarg)) { regs[r].xform = L1WAV; regs[r].xflags = 7u; } else if (0 == strcmp("2", optarg)) { regs[r].xform = L2IMG; } else { error("Unknown regularization type.\n"); } p->lambda = -1.; p->r++; break; } return false; } int main_sqpics(int argc, char* argv[]) { // Initialize default parameters bool use_gpu = false; bool randshift = true; unsigned int maxiter = 30; float step = -1.; // Start time count double start_time = timestamp(); // Read input options struct nufft_conf_s nuconf = nufft_conf_defaults; nuconf.toeplitz = false; float restrict_fov = -1.; const char* pat_file = NULL; const char* traj_file = NULL; bool scale_im = false; bool eigen = false; float scaling = 0.; unsigned int llr_blk = 8; const char* image_truth_file = NULL; bool im_truth = false; const char* image_start_file = NULL; bool warm_start = false; bool hogwild = false; bool fast = false; float admm_rho = iter_admm_defaults.rho; unsigned int admm_maxitercg = iter_admm_defaults.maxitercg; struct opt_reg_s ropts; ropts.r = 0; ropts.algo = CG; ropts.lambda = -1.; const struct opt_s opts[] = { { 'l', true, opt_reg, &ropts, "1/-l2\t\ttoggle l1-wavelet or l2 regularization." }, OPT_FLOAT('r', &ropts.lambda, "lambda", "regularization parameter"), { 'R', true, opt_reg, &ropts, " :A:B:C\tgeneralized regularization options (-Rh for help)" }, //OPT_SET('c', &conf.rvc, "real-value constraint"), OPT_FLOAT('s', &step, "step", "iteration stepsize"), OPT_UINT('i', &maxiter, "iter", "max. number of iterations"), OPT_STRING('t', &traj_file, "file", "k-space trajectory"), OPT_CLEAR('n', &randshift, "disable random wavelet cycle spinning"), OPT_SET('g', &use_gpu, "use GPU"), OPT_STRING('p', &pat_file, "file", "pattern or weights"), OPT_SELECT('I', enum algo_t, &ropts.algo, IST, "(select IST)"), OPT_UINT('b', &llr_blk, "blk", "Lowrank block size"), OPT_SET('e', &eigen, "Scale stepsize based on max. eigenvalue"), OPT_SET('H', &hogwild, "(hogwild)"), OPT_SET('F', &fast, "(fast)"), OPT_STRING('T', &image_truth_file, "file", "(truth file)"), OPT_STRING('W', &image_start_file, "", "Warm start with "), OPT_INT('d', &debug_level, "level", "Debug level"), OPT_FLOAT('u', &admm_rho, "rho", "ADMM rho"), OPT_UINT('C', &admm_maxitercg, "iter", "ADMM max. CG iterations"), OPT_FLOAT('f', &restrict_fov, "rfov", "restrict FOV"), OPT_SELECT('m', enum algo_t, &ropts.algo, ADMM, "Select ADMM"), OPT_FLOAT('w', &scaling, "val", "scaling"), OPT_SET('S', &scale_im, "Re-scale the image after reconstruction"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (NULL != image_truth_file) im_truth = true; if (NULL != image_start_file) warm_start = true; long max_dims[DIMS]; long map_dims[DIMS]; long pat_dims[DIMS]; long img_dims[DIMS]; long coilim_dims[DIMS]; long ksp_dims[DIMS]; long traj_dims[DIMS]; // load kspace and maps and get dimensions complex float* kspace = load_cfl(argv[1], DIMS, ksp_dims); complex float* maps = load_cfl(argv[2], DIMS, map_dims); complex float* traj = NULL; if (NULL != traj_file) traj = load_cfl(traj_file, DIMS, traj_dims); md_copy_dims(DIMS, max_dims, ksp_dims); md_copy_dims(5, max_dims, map_dims); md_select_dims(DIMS, ~COIL_FLAG, img_dims, max_dims); md_select_dims(DIMS, ~MAPS_FLAG, coilim_dims, max_dims); if (!md_check_compat(DIMS, ~(MD_BIT(MAPS_DIM)|FFT_FLAGS), img_dims, map_dims)) error("Dimensions of image and sensitivities do not match!\n"); assert(1 == ksp_dims[MAPS_DIM]); (use_gpu ? num_init_gpu : num_init)(); // print options if (use_gpu) debug_printf(DP_INFO, "GPU reconstruction\n"); if (map_dims[MAPS_DIM] > 1) debug_printf(DP_INFO, "%ld maps.\nESPIRiT reconstruction.\n", map_dims[MAPS_DIM]); if (hogwild) debug_printf(DP_INFO, "Hogwild stepsize\n"); if (im_truth) debug_printf(DP_INFO, "Compare to truth\n"); // initialize sampling pattern complex float* pattern = NULL; if (NULL != pat_file) { pattern = load_cfl(pat_file, DIMS, pat_dims); assert(md_check_compat(DIMS, COIL_FLAG, ksp_dims, pat_dims)); } else { md_select_dims(DIMS, ~COIL_FLAG, pat_dims, ksp_dims); pattern = md_alloc(DIMS, pat_dims, CFL_SIZE); estimate_pattern(DIMS, ksp_dims, COIL_FLAG, pattern, kspace); } if ((NULL != traj_file) && (NULL == pat_file)) { md_free(pattern); pattern = NULL; nuconf.toeplitz = true; } else { // print some statistics long T = md_calc_size(DIMS, pat_dims); long samples = (long)pow(md_znorm(DIMS, pat_dims, pattern), 2.); debug_printf(DP_INFO, "Size: %ld Samples: %ld Acc: %.2f\n", T, samples, (float)T / (float)samples); } if (NULL == traj_file) { fftmod(DIMS, ksp_dims, FFT_FLAGS, kspace, kspace); fftmod(DIMS, map_dims, FFT_FLAGS, maps, maps); } // apply fov mask to sensitivities if (-1. != restrict_fov) { float restrict_dims[DIMS] = { [0 ... DIMS - 1] = 1. }; restrict_dims[0] = restrict_fov; restrict_dims[1] = restrict_fov; restrict_dims[2] = restrict_fov; apply_mask(DIMS, map_dims, maps, restrict_dims); } // initialize forward_op and precond_op const struct linop_s* forward_op = NULL; const struct operator_s* precond_op = NULL; if (NULL == traj_file) forward_op = sense_init(max_dims, FFT_FLAGS|COIL_FLAG|MAPS_FLAG, maps); else forward_op = sense_nc_init(max_dims, map_dims, maps, ksp_dims, traj_dims, traj, nuconf, (struct operator_s**) &precond_op); // apply scaling if (scaling == 0.) { if (NULL == traj_file) { scaling = estimate_scaling(ksp_dims, NULL, kspace); } else { complex float* adj = md_alloc(DIMS, img_dims, CFL_SIZE); linop_adjoint(forward_op, DIMS, img_dims, adj, DIMS, ksp_dims, kspace); scaling = estimate_scaling_norm(1., md_calc_size(DIMS, img_dims), adj, false); md_free(adj); } } else debug_printf(DP_DEBUG1, "Scaling: %f\n", scaling); if (scaling != 0.) md_zsmul(DIMS, ksp_dims, kspace, kspace, 1. / scaling); float lambda = ropts.lambda; if (-1. == lambda) lambda = 0.; // if no penalities specified but regularization // parameter is given, add a l2 penalty struct reg_s* regs = ropts.regs; if ((0 == ropts.r) && (lambda > 0.)) { regs[0].xform = L2IMG; regs[0].xflags = 0u; regs[0].jflags = 0u; regs[0].lambda = lambda; ropts.r = 1; } // initialize thresh_op const struct operator_p_s* thresh_ops[NUM_REGS] = { NULL }; const struct linop_s* trafos[NUM_REGS] = { NULL }; int nr_penalties = ropts.r; long blkdims[MAX_LEV][DIMS]; int levels; for (int nr = 0; nr < nr_penalties; nr++) { // fix up regularization parameter if (-1. == regs[nr].lambda) regs[nr].lambda = lambda; switch (regs[nr].xform) { case L1WAV: debug_printf(DP_INFO, "l1-wavelet regularization: %f\n", regs[nr].lambda); long minsize[DIMS] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(img_dims[0], 16); minsize[1] = MIN(img_dims[1], 16); minsize[2] = MIN(img_dims[2], 16); unsigned int wflags = 0; for (unsigned int i = 0; i < DIMS; i++) { if ((1 < img_dims[i]) && MD_IS_SET(regs[nr].xflags, i)) { wflags = MD_SET(wflags, i); minsize[i] = MIN(img_dims[i], 16); } } trafos[nr] = linop_identity_create(DIMS, img_dims); thresh_ops[nr] = prox_wavelet_thresh_create(DIMS, img_dims, wflags, regs[nr].jflags, minsize, regs[nr].lambda, randshift); break; case TV: debug_printf(DP_INFO, "TV regularization: %f\n", regs[nr].lambda); trafos[nr] = linop_grad_create(DIMS, img_dims, DIMS, regs[nr].xflags); thresh_ops[nr] = prox_thresh_create(DIMS + 1, linop_codomain(trafos[nr])->dims, regs[nr].lambda, regs[nr].jflags | MD_BIT(DIMS)); break; case LLR: debug_printf(DP_INFO, "lowrank regularization: %f\n", regs[nr].lambda); // add locally lowrank penalty levels = llr_blkdims(blkdims, regs[nr].jflags, img_dims, llr_blk); assert(1 == levels); img_dims[LEVEL_DIM] = levels; for(int l = 0; l < levels; l++) #if 0 blkdims[l][MAPS_DIM] = img_dims[MAPS_DIM]; #else blkdims[l][MAPS_DIM] = 1; #endif int remove_mean = 0; trafos[nr] = linop_identity_create(DIMS, img_dims); thresh_ops[nr] = lrthresh_create(img_dims, randshift, regs[nr].xflags, (const long (*)[DIMS])blkdims, regs[nr].lambda, false, remove_mean, false); break; case MLR: debug_printf(DP_INFO, "multi-scale lowrank regularization: %f\n", regs[nr].lambda); levels = multilr_blkdims(blkdims, regs[nr].jflags, img_dims, 8, 1); img_dims[LEVEL_DIM] = levels; max_dims[LEVEL_DIM] = levels; for(int l = 0; l < levels; l++) blkdims[l][MAPS_DIM] = 1; trafos[nr] = linop_identity_create(DIMS, img_dims); thresh_ops[nr] = lrthresh_create(img_dims, randshift, regs[nr].xflags, (const long (*)[DIMS])blkdims, regs[nr].lambda, false, 0, false); const struct linop_s* decom_op = linop_sum_create(img_dims); const struct linop_s* tmp_op = forward_op; forward_op = linop_chain(decom_op, forward_op); linop_free(decom_op); linop_free(tmp_op); break; case IMAGL1: debug_printf(DP_INFO, "l1 regularization of imaginary part: %f\n", regs[nr].lambda); trafos[nr] = linop_rdiag_create(DIMS, img_dims, 0, &(complex float){ 1.i }); thresh_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags); break; case IMAGL2: debug_printf(DP_INFO, "l2 regularization of imaginary part: %f\n", regs[nr].lambda); trafos[nr] = linop_rdiag_create(DIMS, img_dims, 0, &(complex float){ 1.i }); thresh_ops[nr] = prox_leastsquares_create(DIMS, img_dims, regs[nr].lambda, NULL); break; case L1IMG: debug_printf(DP_INFO, "l1 regularization: %f\n", regs[nr].lambda); trafos[nr] = linop_identity_create(DIMS, img_dims); thresh_ops[nr] = prox_thresh_create(DIMS, img_dims, regs[nr].lambda, regs[nr].jflags); break; case L2IMG: debug_printf(DP_INFO, "l2 regularization: %f\n", regs[nr].lambda); trafos[nr] = linop_identity_create(DIMS, img_dims); thresh_ops[nr] = prox_leastsquares_create(DIMS, img_dims, regs[nr].lambda, NULL); break; } } int nr = nr_penalties; struct linop_s* sampling = linop_sampling_create(max_dims, pat_dims, pattern); struct linop_s* tmp_op = linop_chain(forward_op, sampling); linop_free(sampling); linop_free(forward_op); forward_op = tmp_op; trafos[nr] = forward_op; thresh_ops[nr] = prox_l2norm_create(DIMS, ksp_dims, 1.); nr_penalties++; const float** biases = xmalloc(sizeof(float*) * nr_penalties); for (int i = 0; i < nr_penalties - 1; i++) biases[i] = NULL; biases[nr] = (float*)kspace; complex float* image = create_cfl(argv[3], DIMS, img_dims); md_clear(DIMS, img_dims, image, CFL_SIZE); long img_truth_dims[DIMS]; complex float* image_truth = NULL; if (im_truth) { image_truth = load_cfl(image_truth_file, DIMS, img_truth_dims); //md_zsmul(DIMS, img_dims, image_truth, image_truth, 1. / scaling); } long img_start_dims[DIMS]; complex float* image_start = NULL; if (warm_start) { debug_printf(DP_DEBUG1, "Warm start: %s\n", image_start_file); image_start = load_cfl(image_start_file, DIMS, img_start_dims); assert(md_check_compat(DIMS, 0u, img_start_dims, img_dims)); md_copy(DIMS, img_dims, image, image_start, CFL_SIZE); free((void*)image_start_file); unmap_cfl(DIMS, img_dims, image_start); // if rescaling at the end, assume the input has also been rescaled if (scale_im && scaling != 0.) md_zsmul(DIMS, img_dims, image, image, 1. / scaling); } // initialize algorithm struct iter_admm_conf mmconf; debug_printf(DP_INFO, "ADMM\n"); mmconf = iter_admm_defaults; mmconf.maxiter = maxiter; mmconf.maxitercg = admm_maxitercg; mmconf.rho = admm_rho; mmconf.hogwild = hogwild; mmconf.fast = fast; //mmconf.dynamic_rho = true; mmconf.ABSTOL = 0.; mmconf.RELTOL = 0.; long size = 2 * md_calc_size(DIMS, img_dims); iter2_admm(CAST_UP(&mmconf), NULL, nr_penalties, thresh_ops, trafos, biases, NULL, size, (float*)image, NULL, NULL); #if 0 if (use_gpu) #ifdef USE_CUDA sqpics_recon2_gpu(&conf, max_dims, image, forward_op, pat_dims, pattern, italgo, iconf, nr_penalties, thresh_ops, (ADMM == algo) ? trafos : NULL, ksp_dims, kspace, image_truth, precond_op); #else assert(0); #endif else sqpics_recon2(&conf, max_dims, image, forward_op, pat_dims, pattern, italgo, iconf, nr_penalties, thresh_ops, (ADMM == algo) ? trafos : NULL, ksp_dims, kspace, image_truth, precond_op); #endif if (scale_im) md_zsmul(DIMS, img_dims, image, image, scaling); // clean up if (NULL != pat_file) unmap_cfl(DIMS, pat_dims, pattern); else md_free(pattern); unmap_cfl(DIMS, map_dims, maps); unmap_cfl(DIMS, ksp_dims, kspace); unmap_cfl(DIMS, img_dims, image); if (NULL != traj) unmap_cfl(DIMS, traj_dims, traj); if (im_truth) { free((void*)image_truth_file); unmap_cfl(DIMS, img_dims, image_truth); } double end_time = timestamp(); debug_printf(DP_INFO, "Total Time: %f\n", end_time - start_time); return 0; } bart-0.5.00/src/squeeze.c000066400000000000000000000022231353046746100151500ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jon Tamir */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #ifndef DIMS #define DIMS 32 #endif static const char usage_str[] = " "; static const char help_str[] = "Remove singleton dimensions of array.\n"; int main_squeeze(int argc, char* argv[]) { mini_cmdline(&argc, argv, 2, usage_str, help_str); num_init(); long idims[DIMS]; long odims[DIMS] = MD_INIT_ARRAY(DIMS, 1); complex float* idata = load_cfl(argv[1], DIMS, idims); unsigned int j = 0; for (unsigned int i = 0; i < DIMS; i++) if (1 < idims[i]) odims[j++] = idims[i]; if (0 == j) j = 1; complex float* odata = create_cfl(argv[2], j, odims); md_copy(DIMS, idims, odata, idata, CFL_SIZE); unmap_cfl(DIMS, idims, idata); unmap_cfl(j, odims, odata); return 0; } bart-0.5.00/src/std.c000066400000000000000000000021451353046746100142640ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Jon Tamir */ #include #include #include #include "num/multind.h" #include "num/init.h" #include "num/flpmath.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Compute standard deviation along selected dimensions specified by the {bitmask}"; int main_std(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); long flags = atoi(argv[1]); long idims[DIMS]; long odims[DIMS]; complex float* in = load_cfl(argv[2], DIMS, idims); md_select_dims(DIMS, ~flags, odims, idims); complex float* out = create_cfl(argv[3], DIMS, odims); md_zstd(DIMS, idims, flags, out, in); unmap_cfl(DIMS, idims, in); unmap_cfl(DIMS, odims, out); return 0; } bart-0.5.00/src/svd.c000066400000000000000000000032671353046746100142740ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013, 2015 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/lapack.h" #include "misc/misc.h" #include "misc/mmio.h" #include "misc/opts.h" static const char usage_str[] = " "; static const char help_str[] = "Compute singular-value-decomposition (SVD).\n"; int main_svd(int argc, char* argv[]) { bool econ = false; const struct opt_s opts[] = { OPT_SET('e', &econ, "econ"), }; cmdline(&argc, argv, 4, 4, usage_str, help_str, ARRAY_SIZE(opts), opts); int N = 2; long dims[N]; complex float* in = load_cfl(argv[1], N, dims); long dimsU[2] = { dims[0], econ ? MIN(dims[0], dims[1]) : dims[0] }; long dimsS[2] = { MIN(dims[0], dims[1]), 1 }; long dimsVH[2] = { econ ? MIN(dims[0], dims[1]) : dims[1], dims[1] }; complex float* U = create_cfl(argv[2], N, dimsU); complex float* S = create_cfl(argv[3], N, dimsS); complex float* VH = create_cfl(argv[4], N, dimsVH); float* SF = md_alloc(2, dimsS, FL_SIZE); (econ ? lapack_svd_econ : lapack_svd)(dims[0], dims[1], MD_CAST_ARRAY2(complex float, 2, dimsU, U, 0, 1), MD_CAST_ARRAY2(complex float, 2, dimsVH, VH, 0, 1), SF, MD_CAST_ARRAY2(complex float, 2, dims, in, 0, 1)); for (int i = 0 ; i < dimsS[0]; i++) S[i] = SF[i]; md_free(SF); unmap_cfl(N, dims, in); unmap_cfl(N, dimsU, U); unmap_cfl(N, dimsS, S); unmap_cfl(N, dimsVH, VH); return 0; } bart-0.5.00/src/tgv.c000066400000000000000000000100421353046746100142650ustar00rootroot00000000000000/* Copyright 2014,2019. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014,2019 Martin Uecker * * * Rudin LI, Osher S, Fatemi E. Nonlinear total variation based * noise removal algorithms, Physica D: Nonlinear Phenomena * 60:259-268 (1992) * * Bredies K, Kunisch K, Pock T. Total generalized variation. * SIAM Journal on Imaging Sciences * 3:492-526 (2010) */ #include #include #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "num/ops_p.h" #include "num/init.h" #include "linops/linop.h" #include "linops/someops.h" #include "linops/grad.h" #include "misc/mmio.h" #include "misc/misc.h" #include "iter/prox.h" #include "iter/thresh.h" #include "iter/iter2.h" #include "iter/iter.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Perform total generalized variation denoising along dims .\n"; /* TGV * * min x \|Ix - y\|_2^2 + min z \alpha \|grad x - z \|_1 + \beta \|eps z \|_1 * * min x,z \| Ix - y \|_2^2 + \alpha \|grad x - z\|_1 + \beta \|eps z\|_1 * */ int main_tgv(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); float lambda = atof(argv[1]); int flags = atoi(argv[2]); long in_dims[DIMS]; complex float* in_data = load_cfl(argv[3], DIMS, in_dims); assert(1 == in_dims[DIMS - 1]); long out_dims[DIMS]; const struct linop_s* grad1 = linop_grad_create(DIMS - 1, in_dims, DIMS - 1, flags); const struct linop_s* grad2x = linop_grad_create(DIMS + 0, linop_codomain(grad1)->dims, DIMS + 0, flags); auto grad2a = linop_transpose_create(DIMS + 1, DIMS - 1, DIMS + 0, linop_codomain(grad2x)->dims); auto grad2b = linop_identity_create(DIMS + 1, linop_codomain(grad2x)->dims); auto grad2c = linop_plus(grad2a, grad2b); linop_free(grad2a); linop_free(grad2b); auto grad2 = linop_chain(grad2x, grad2c); linop_free(grad2x); linop_free(grad2c); long grd_dims[DIMS]; md_copy_dims(DIMS, grd_dims, linop_codomain(grad1)->dims); md_copy_dims(DIMS, out_dims, grd_dims); out_dims[DIMS - 1]++; complex float* out_data = create_cfl(argv[4], DIMS, out_dims); long pos1[DIMS] = { [DIMS - 1] = 0 }; auto grad1b = linop_extract_create(DIMS, pos1, in_dims, out_dims); auto grad1c = linop_reshape_create(DIMS - 1, linop_domain(grad1)->dims, DIMS, in_dims); auto grad1d1 = linop_chain(grad1b, grad1c); auto grad1d = linop_chain(grad1d1, grad1); linop_free(grad1); linop_free(grad1b); linop_free(grad1c); linop_free(grad1d1); long pos1b[DIMS] = { [DIMS - 1] = 1 }; auto grad1e = linop_extract_create(DIMS, pos1b, grd_dims, out_dims); const struct linop_s* grad1f = linop_plus(grad1e, grad1d); linop_free(grad1e); linop_free(grad1d); long pos2[DIMS] = { [DIMS - 1] = 1 }; auto grad2e = linop_extract_create(DIMS, pos2, grd_dims, out_dims); const struct linop_s* grad2f = linop_chain(grad2e, grad2); linop_free(grad2); linop_free(grad2e); auto p1 = prox_thresh_create(DIMS + 0, linop_codomain(grad1f)->dims, lambda, 0u); auto p2 = prox_thresh_create(DIMS + 1, linop_codomain(grad2f)->dims, lambda, 0u); auto id = linop_extract_create(DIMS, (long[DIMS]){ 0 }, in_dims, out_dims); struct iter_admm_conf conf = iter_admm_defaults; complex float* adj = md_alloc(DIMS, out_dims, CFL_SIZE); linop_adjoint(id, DIMS, out_dims, adj, DIMS, in_dims, in_data); conf.maxiter = 100; conf.rho = .1; iter2_admm(CAST_UP(&conf), id->normal, 2, MAKE_ARRAY(p1, p2), MAKE_ARRAY(grad1f, grad2f), NULL, NULL, 2 * md_calc_size(DIMS, out_dims), (float*)out_data, (const float*)adj, NULL); md_free(adj); linop_free(id); linop_free(grad1f); linop_free(grad2c); operator_p_free(p1); operator_p_free(p2); unmap_cfl(DIMS, in_dims, in_data); unmap_cfl(DIMS, out_dims, out_data); return 0; } bart-0.5.00/src/threshold.c000066400000000000000000000110361353046746100154650ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2017 Martin Uecker * 2015-2016 Jon Tamir * 2015 Frank Ong */ #include #include #include "num/flpmath.h" #include "num/multind.h" #include "num/init.h" #include "num/ops_p.h" #include "iter/prox.h" #include "iter/thresh.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "lowrank/lrthresh.h" #include "linops/waveop.h" #include "dfwavelet/prox_dfwavelet.h" // FIXME: lowrank interface should not be coupled to mri.h -- it should take D as an input #ifndef DIMS #define DIMS 16 #endif // FIXME: consider moving this to a more accessible location? static void wthresh(unsigned int D, const long dims[D], float lambda, unsigned int flags, complex float* out, const complex float* in) { long minsize[D]; md_singleton_dims(D, minsize); long course_scale[3] = MD_INIT_ARRAY(3, 16); md_copy_dims(3, minsize, course_scale); unsigned int wflags = 7; // FIXME for (unsigned int i = 0; i < 3; i++) if (dims[i] < minsize[i]) wflags = MD_CLEAR(wflags, i); long strs[D]; md_calc_strides(D, strs, dims, CFL_SIZE); const struct linop_s* w = linop_wavelet_create(D, wflags, dims, strs, minsize, false); const struct operator_p_s* p = prox_unithresh_create(D, w, lambda, flags); operator_p_apply(p, 1., D, dims, out, D, dims, in); operator_p_free(p); } static void lrthresh(unsigned int D, const long dims[D], int llrblk, float lambda, unsigned int flags, complex float* out, const complex float* in) { long blkdims[MAX_LEV][D]; int levels = llr_blkdims(blkdims, ~flags, dims, llrblk); UNUSED(levels); const struct operator_p_s* p = lrthresh_create(dims, false, ~flags, (const long (*)[])blkdims, lambda, false, false, false); operator_p_apply(p, 1., D, dims, out, D, dims, in); operator_p_free(p); } static void dfthresh(unsigned int D, const long dims[D], float lambda, complex float* out, const complex float* in) { long minsize[3]; md_singleton_dims(3, minsize); long coarse_scale[3] = MD_INIT_ARRAY(3, 16); md_min_dims(3, ~0u, minsize, dims, coarse_scale); complex float res[3]; res[0] = 1.; res[1] = 1.; res[2] = 1.; assert(3 == dims[TE_DIM]); const struct operator_p_s* p = prox_dfwavelet_create(dims, minsize, res, TE_DIM, lambda, false); operator_p_apply(p, 1., D, dims, out, D, dims, in); operator_p_free(p); } static void hard_thresh(unsigned int D, const long dims[D], float lambda, complex float* out, const complex float* in) { long size = md_calc_size(DIMS, dims) * 2; const float* inf = (const float*)in; float* outf = (float*)out; #pragma omp parallel for for (long i = 0; i < size; i++) outf[i] = inf[i] > lambda ? inf[i] : 0.; } static const char usage_str[] = "lambda "; static const char help_str[] = "Perform (soft) thresholding with parameter lambda."; int main_threshold(int argc, char* argv[]) { unsigned int flags = 0; enum th_type { NONE, WAV, LLR, DFW, MPDFW, HARD } th_type = NONE; int llrblk = 8; const struct opt_s opts[] = { OPT_SELECT('H', enum th_type, &th_type, HARD, "hard thresholding"), OPT_SELECT('W', enum th_type, &th_type, WAV, "daubechies wavelet soft-thresholding"), OPT_SELECT('L', enum th_type, &th_type, LLR, "locally low rank soft-thresholding"), OPT_SELECT('D', enum th_type, &th_type, DFW, "divergence-free wavelet soft-thresholding"), OPT_UINT('j', &flags, "bitmask", "joint soft-thresholding"), OPT_INT('b', &llrblk, "blocksize", "locally low rank block size"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); const int N = DIMS; long dims[N]; complex float* idata = load_cfl(argv[2], N, dims); complex float* odata = create_cfl(argv[3], N, dims); float lambda = atof(argv[1]); switch (th_type) { case WAV: wthresh(N, dims, lambda, flags, odata, idata); break; case LLR: lrthresh(N, dims, llrblk, lambda, flags, odata, idata); break; case DFW: dfthresh(N, dims, lambda, odata, idata); break; case HARD: hard_thresh(N, dims, lambda, odata, idata); break; default: md_zsoftthresh(N, dims, lambda, flags, odata, idata); } unmap_cfl(N, dims, idata); unmap_cfl(N, dims, odata); return 0; } bart-0.5.00/src/toimg.c000066400000000000000000000112561353046746100146140ustar00rootroot00000000000000/* Copyright 2013-2018 The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013, 2015 Martin Uecker * 2015, 2018 Jon Tamir */ #include #include #include #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "num/flpmath.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/mmio.h" #include "misc/png.h" #include "misc/dicom.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif static const char usage_str[] = "[-h] "; static const char help_str[] = "Create magnitude images as png or proto-dicom.\n" "The first two non-singleton dimensions will\n" "be used for the image, and the other dimensions\n" "will be looped over.\n"; // from view:src/draw.c static double clamp(double a, double b, double x) { return (x < a) ? a : ((x > b) ? b : x); } static double windowing(double g, double a, double b, double x) { return pow(clamp(0., 1., (x - a) / (b - a)), g); } static void toimg(bool dicom, bool use_windowing, const char* name, long inum, float gamma, float contrast, float window, float scale, long h, long w, const complex float* data) { int len = strlen(name); assert(len >= 1); int nr_bytes = dicom ? 2 : 3; unsigned char (*buf)[h][w][nr_bytes] = TYPE_ALLOC(unsigned char[h][w][nr_bytes]); float max_val = dicom ? 65535. : 255.; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { double val = cabsf(data[j * h + i]) / scale; unsigned int value = (unsigned int)(max_val * (use_windowing ? windowing(gamma, contrast, window, val) : val)); if (!dicom) { (*buf)[i][j][0] = value; (*buf)[i][j][1] = value; (*buf)[i][j][2] = value; } else { (*buf)[i][j][0] = (value >> 0) & 0xFF; (*buf)[i][j][1] = (value >> 8) & 0xFF; } } } (dicom ? dicom_write : png_write_rgb24)(name, w, h, inum, &(*buf)[0][0][0]); free(buf); } static void toimg_stack(const char* name, bool dicom, bool single_scale, bool use_windowing, float gamma, float contrast, float window, const long dims[DIMS], const complex float* data) { long data_size = md_calc_size(DIMS, dims); long sq_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; int l = 0; for (int i = 0; i < DIMS; i++) if (1 != dims[i]) sq_dims[l++] = dims[i]; float max = 0.; for (long i = 0; i < data_size; i++) max = MAX(cabsf(data[i]), max); int len = strlen(name); assert(len >= 1); long num_imgs = md_calc_size(DIMS - 2, sq_dims + 2); long img_size = md_calc_size(2, sq_dims); debug_printf(DP_INFO, "Writing %d image(s)...", num_imgs); #pragma omp parallel for for (long i = 0; i < num_imgs; i++) { char name_i[len + 10]; // extra space for ".0000.png" if (num_imgs > 1) sprintf(name_i, "%s-%04ld.%s", name, i, dicom ? "dcm" : "png"); else sprintf(name_i, "%s.%s", name, dicom ? "dcm" : "png"); float scale = 0.; if (use_windowing) scale = md_znorm(2, sq_dims, data + i * img_size) / md_calc_size(2, sq_dims); else if (single_scale) scale = max; else for (long j = 0; j < md_calc_size(2, sq_dims); j++) scale = MAX(cabsf(data[i * img_size + j]), scale); if (0. == scale) scale = 1.; toimg(dicom, use_windowing, name_i, i, gamma, contrast, window, scale, sq_dims[0], sq_dims[1], data + i * img_size); } debug_printf(DP_INFO, "done.\n", num_imgs); } int main_toimg(int argc, char* argv[]) { float gamma = 1.; float contrast = 0.; float window = 750.; bool use_windowing = false; bool single_scale = true; bool dicom = false; const struct opt_s opts[] = { OPT_FLOAT('g', &gamma, "gamma", "gamma level"), OPT_FLOAT('c', &contrast, "contrast", "contrast level"), OPT_FLOAT('w', &window, "window", "window level"), OPT_SET('d', &dicom, "write to dicom format (deprecated, use extension .dcm)"), OPT_CLEAR('m', &single_scale, "re-scale each image"), OPT_SET('W', &use_windowing, "use dynamic windowing"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); char* ext = rindex(argv[2], '.'); if (NULL != ext) { assert(!dicom); if (0 == strcmp(ext, ".dcm")) dicom = true; else if (0 != strcmp(ext, ".png")) error("Unknown file extension."); *ext = '\0'; } long dims[DIMS]; complex float* data = load_cfl(argv[1], DIMS, dims); toimg_stack(argv[2], dicom, single_scale, use_windowing, gamma, contrast, window, dims, data); unmap_cfl(DIMS, dims, data); return 0; } bart-0.5.00/src/traj.c000066400000000000000000000142361353046746100144360ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2015-2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-2019 Martin Uecker * 2018-2019 Sebastian Rosenzweig * 2019 Aurélien Trotier */ #include #include #include #include #include "num/flpmath.h" #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/opts.h" #include "misc/debug.h" #include "noncart/traj.h" static const char usage_str[] = ""; static const char help_str[] = "Computes k-space trajectories."; int main_traj(int argc, char* argv[]) { int X = 128; int Y = 128; int mb = 1; int turns = 1; float rot = 0.; struct traj_conf conf = traj_defaults; float gdelays[2][3] = { { 0., 0., 0. }, { 0., 0., 0. } }; long z_usamp[2] = { 0, 1 }; // { reference Lines, acceleration } const char* custom_angle = NULL; const struct opt_s opts[] = { OPT_INT('x', &X, "x", "readout samples"), OPT_INT('y', &Y, "y", "phase encoding lines"), OPT_INT('a', &conf.accel, "a", "acceleration"), OPT_INT('t', &turns, "t", "turns"), OPT_INT('m', &mb, "mb", "SMS multiband factor"), OPT_SET('l', &conf.aligned, "aligned partition angle"), OPT_SET('g', &conf.golden_partition, "golden angle in partition direction"), OPT_SET('r', &conf.radial, "radial"), OPT_SET('G', &conf.golden, "golden-ratio sampling"), OPT_SET('H', &conf.half_circle_gold, "halfCircle golden-ratio sampling"), OPT_INT('s', &conf.tiny_gold, "# Tiny GA", "tiny golden angle"), OPT_SET('D', &conf.full_circle, "projection angle in [0,360°), else in [0,180°)"), OPT_FLOAT('R', &rot, "phi", "rotate"), OPT_FLVEC3('q', &gdelays[0], "delays", "gradient delays: x, y, xy"), OPT_FLVEC3('Q', &gdelays[1], "delays", "(gradient delays: z, xz, yz)"), OPT_SET('O', &conf.transverse, "correct transverse gradient error for radial tajectories"), OPT_SET('3', &conf.d3d, "3D"), OPT_SET('c', &conf.asym_traj, "asymmetric trajectory [DC sampled]"), OPT_VEC2('z', &z_usamp, "Ref:Acel", "Undersampling in z-direction."), OPT_STRING('C', &custom_angle, "file", "custom_angle"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); // Load custom_angle long sdims[DIMS]; complex float* custom_angle_val = NULL; if (NULL != custom_angle && conf.radial) { debug_printf(DP_INFO, "custom_angle file is used \n"); custom_angle_val = load_cfl(custom_angle, DIMS, sdims); if(Y != sdims[0]){ debug_printf(DP_INFO, "According to the custom angle file : y = %d\n",sdims[0]); Y = sdims[0]; } } int tot_sp = Y * mb * turns; // total number of lines/spokes int N = X * tot_sp / conf.accel; long dims[DIMS] = { [0 ... DIMS - 1] = 1 }; dims[0] = 3; dims[1] = X; dims[2] = (conf.radial ? Y : (Y / conf.accel)); // Variables for z-undersampling long z_reflines = z_usamp[0]; long z_acc = z_usamp[1]; long mb2 = mb; if (z_acc > 1) { mb2 = z_reflines + (mb - z_reflines) / z_acc; if ((mb2 < 1) || ((mb - z_reflines) % z_acc != 0)) error("Invalid z-Acceleration!\n"); } dims[TIME_DIM] = turns; dims[SLICE_DIM] = mb; if (conf.half_circle_gold) { conf.golden = true; if (conf.full_circle) error("Invalid options. Full-circle or half-circle sampling?"); } if (conf.d3d) { if (turns >1) error("Turns not implemented for 3D-Kooshball\n"); if (mb > 1) error("Multiple partitions not sensible for 3D-Kooshball\n"); } if (conf.tiny_gold >= 1) conf.golden = true; if (conf.golden) { conf.radial = true; if (0 == conf.tiny_gold) conf.tiny_gold = 1; } else if (conf.full_circle || conf.radial) { conf.radial = true; } else { // Cartesian if ((turns != 1) || (mb != 1)) error("Turns or partitions not allowed/implemented for Cartesian trajectories!"); } complex float* samples = create_cfl(argv[1], DIMS, dims); md_clear(DIMS, dims, samples, CFL_SIZE); double golden_ratio = (sqrtf(5.) + 1.) / 2; double angle_atom = M_PI / Y; double base_angle[DIMS] = { 0. }; calc_base_angles(base_angle, Y, mb2, turns, conf); int p = 0; long pos[DIMS] = { 0 }; do { int i = pos[PHS1_DIM]; int j = pos[PHS2_DIM]; int m = pos[SLICE_DIM]; if (conf.radial) { int s = j; /* Calculate read-out samples * for symmetric trajectory [DC between between sample no. X/2-1 and X/2, zero-based indexing] * or asymmetric trajectory [DC component at sample no. X/2, zero-based indexing] */ double read = (float)i + (conf.asym_traj ? 0 : 0.5) - (float)X / 2.; if (conf.golden_partition) base_angle[1] = (m > 0) ? (fmod(angle_atom * m / golden_ratio, angle_atom) / m) : 0; double angle = 0.; for (unsigned int d = 1; d < DIMS; d++) angle += pos[d] * base_angle[d]; if (conf.half_circle_gold) angle = fmod(angle, M_PI); angle += M_PI * rot / 180.; // 3D double angle2 = 0.; if (conf.d3d) { int split = sqrtf(Y); angle2 = s * M_PI / Y * (conf.full_circle ? 2 : 1) * split; if (NULL != custom_angle) angle2 = cimag(custom_angle_val[p%X]); } if (NULL != custom_angle) angle = creal(custom_angle_val[p%X]); float d[3] = { 0., 0., 0 }; gradient_delay(d, gdelays, angle, angle2); float read_dir[3]; euler(read_dir, angle, angle2); if (!conf.transverse) { // project to read direction float delay = 0.; for (unsigned int i = 0; i < 3; i++) delay += read_dir[i] * d[i]; for (unsigned int i = 0; i < 3; i++) d[i] = delay * read_dir[i]; } samples[p * 3 + 0] = d[1] + read * read_dir[1]; samples[p * 3 + 1] = d[0] + read * read_dir[0]; samples[p * 3 + 2] = d[2] + read * read_dir[2]; } else { samples[p * 3 + 0] = (i - X / 2); samples[p * 3 + 1] = (j - Y / 2); samples[p * 3 + 2] = 0; } p++; } while(md_next(DIMS, dims, ~1L, pos)); assert(p == N - 0); if (NULL != custom_angle_val) unmap_cfl(3, sdims, custom_angle_val); unmap_cfl(3, dims, samples); exit(0); } bart-0.5.00/src/transpose.c000066400000000000000000000023071353046746100155100ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/mri.h" #include "misc/misc.h" static const char usage_str[] = "dim1 dim2 "; static const char help_str[] = "Transpose dimensions {dim1} and {dim2}.\n"; int main_transpose(int argc, char* argv[]) { mini_cmdline(&argc, argv, 4, usage_str, help_str); num_init(); int N = DIMS; long idims[N]; int dim1 = atoi(argv[1]); int dim2 = atoi(argv[2]); assert((0 <= dim1) && (dim1 < N)); assert((0 <= dim2) && (dim2 < N)); complex float* idata = load_cfl(argv[3], N, idims); long odims[N]; md_transpose_dims(N, dim1, dim2, odims, idims); complex float* odata = create_cfl(argv[4], N, odims); md_transpose(N, dim1, dim2, odims, odata, idims, idata, sizeof(complex float)); unmap_cfl(N, idims, idata); unmap_cfl(N, odims, odata); return 0; } bart-0.5.00/src/twixread.c000066400000000000000000000201301353046746100153130ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014-2019 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/debug.h" #include "misc/opts.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(complex float) #endif /* Information about twix files can be found here: * (Matlab code by Philipp Ehses and others, Yarra by Tobias Block) * https://github.com/cjohnevans/Gannet2.0/blob/master/mapVBVD.m * https://bitbucket.org/yarra-dev/yarramodules-setdcmtags/src/ */ struct hdr_s { uint32_t offset; uint32_t nscans; }; struct entry_s { uint32_t measid; uint32_t fileid; uint64_t offset; uint64_t length; char patient[64]; char protocol[64]; }; static void xread(int fd, void* buf, size_t size) { if (size != (size_t)read(fd, buf, size)) error("reading file"); } static void xseek(int fd, off_t pos) { if (-1 == lseek(fd, pos, SEEK_SET)) error("seeking"); } static bool siemens_meas_setup(int fd, struct hdr_s* hdr) { off_t start = 0; xseek(fd, start); xread(fd, hdr, sizeof(struct hdr_s)); // check for VD version bool vd = ((0 == hdr->offset) && (hdr->nscans < 64)); if (vd) { assert((0 < hdr->nscans) && (hdr->nscans < 30)); struct entry_s entries[hdr->nscans]; xread(fd, &entries, sizeof(entries)); int n = hdr->nscans - 1; debug_printf(DP_INFO, "VD Header. MeasID: %d FileID: %d Scans: %d\n", entries[n].measid, entries[n].fileid, hdr->nscans); debug_printf(DP_INFO, "Patient: %.64s\nProtocol: %.64s\n", entries[n].patient, entries[n].protocol); start = entries[n].offset; // reread offset xseek(fd, start); xread(fd, &hdr->offset, sizeof(hdr->offset)); } else { debug_printf(DP_INFO, "VB Header.\n"); hdr->nscans = 1; } start += hdr->offset; xseek(fd, start); return vd; } struct mdh2 { // second part of mdh uint32_t evalinfo[2]; uint16_t samples; uint16_t channels; uint16_t sLC[14]; uint16_t dummy1[2]; uint16_t clmnctr; uint16_t dummy2[5]; uint16_t linectr; uint16_t partctr; }; static int siemens_bounds(bool vd, int fd, long min[DIMS], long max[DIMS]) { char scan_hdr[vd ? 192 : 0]; size_t size = sizeof(scan_hdr); if (size != (size_t)read(fd, scan_hdr, size)) return -1; long pos[DIMS] = { 0 }; for (pos[COIL_DIM] = 0; pos[COIL_DIM] < max[COIL_DIM]; pos[COIL_DIM]++) { char chan_hdr[vd ? 32 : 128]; size_t size = sizeof(chan_hdr); if (size != (size_t)read(fd, chan_hdr, size)) return -1; struct mdh2 mdh; memcpy(&mdh, vd ? (scan_hdr + 40) : (chan_hdr + 20), sizeof(mdh)); if (0 == max[READ_DIM]) { max[READ_DIM] = mdh.samples; max[COIL_DIM] = mdh.channels; } if (max[READ_DIM] != mdh.samples) return -1; if (max[COIL_DIM] != mdh.channels) return -1; pos[PHS1_DIM] = mdh.sLC[0]; pos[AVG_DIM] = mdh.sLC[1]; pos[SLICE_DIM] = mdh.sLC[2]; pos[PHS2_DIM] = mdh.sLC[3]; pos[TE_DIM] = mdh.sLC[4]; pos[TIME_DIM] = mdh.sLC[6]; pos[TIME2_DIM] = mdh.sLC[7]; for (unsigned int i = 0; i < DIMS; i++) { max[i] = MAX(max[i], pos[i] + 1); min[i] = MIN(min[i], pos[i] + 0); } size = max[READ_DIM] * CFL_SIZE; char buf[size]; if (size != (size_t)read(fd, buf, size)) return -1; } return 0; } static int siemens_adc_read(bool vd, int fd, bool linectr, bool partctr, const long dims[DIMS], long pos[DIMS], complex float* buf) { char scan_hdr[vd ? 192 : 0]; xread(fd, scan_hdr, sizeof(scan_hdr)); for (pos[COIL_DIM] = 0; pos[COIL_DIM] < dims[COIL_DIM]; pos[COIL_DIM]++) { char chan_hdr[vd ? 32 : 128]; xread(fd, chan_hdr, sizeof(chan_hdr)); struct mdh2 mdh; memcpy(&mdh, vd ? (scan_hdr + 40) : (chan_hdr + 20), sizeof(mdh)); if (0 == pos[COIL_DIM]) { // TODO: rethink this pos[PHS1_DIM] = mdh.sLC[0] + (linectr ? mdh.linectr : 0); pos[AVG_DIM] = mdh.sLC[1]; pos[SLICE_DIM] = mdh.sLC[2]; pos[PHS2_DIM] = mdh.sLC[3] + (partctr ? mdh.partctr : 0); pos[TE_DIM] = mdh.sLC[4]; pos[TIME_DIM] = mdh.sLC[6]; pos[TIME2_DIM] = mdh.sLC[7]; } debug_print_dims(DP_DEBUG4, DIMS, pos); if (dims[READ_DIM] != mdh.samples) { debug_printf(DP_WARN, "Wrong number of samples: %d != %d.\n", dims[READ_DIM], mdh.samples); return -1; } if ((0 != mdh.channels) && (dims[COIL_DIM] != mdh.channels)) { debug_printf(DP_WARN, "Wrong number of channels: %d != %d.\n", dims[COIL_DIM], mdh.channels); return -1; } xread(fd, buf + pos[COIL_DIM] * dims[READ_DIM], dims[READ_DIM] * CFL_SIZE); } pos[COIL_DIM] = 0; return 0; } static const char usage_str[] = " "; // fprintf(fd, "Usage: %s [...] [-a A] \n", name); static const char help_str[] = "Read data from Siemens twix (.dat) files."; int main_twixread(int argc, char* argv[argc]) { long adcs = 0; long radial_lines = -1; bool autoc = false; bool linectr = false; bool partctr = false; bool mpi = false; long dims[DIMS]; md_singleton_dims(DIMS, dims); struct opt_s opts[] = { OPT_LONG('x', &(dims[READ_DIM]), "X", "number of samples (read-out)"), OPT_LONG('r', &radial_lines, "R", "radial lines"), OPT_LONG('y', &(dims[PHS1_DIM]), "Y", "phase encoding steps"), OPT_LONG('z', &(dims[PHS2_DIM]), "Z", "partition encoding steps"), OPT_LONG('s', &(dims[SLICE_DIM]), "S", "number of slices"), OPT_LONG('v', &(dims[AVG_DIM]), "V", "number of averages"), OPT_LONG('c', &(dims[COIL_DIM]), "C", "number of channels"), OPT_LONG('n', &(dims[TIME_DIM]), "N", "number of repetitions"), OPT_LONG('a', &adcs, "A", "total number of ADCs"), OPT_SET('A', &autoc, "automatic [guess dimensions]"), OPT_SET('L', &linectr, "use linectr offset"), OPT_SET('P', &partctr, "use partctr offset"), OPT_SET('M', &mpi, "MPI mode"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); if (-1 != radial_lines) dims[PHS1_DIM] = radial_lines; if (0 == adcs) adcs = dims[PHS1_DIM] * dims[PHS2_DIM] * dims[SLICE_DIM] * dims[TIME_DIM]; debug_print_dims(DP_DEBUG1, DIMS, dims); int ifd; if (-1 == (ifd = open(argv[1], O_RDONLY))) error("error opening file."); struct hdr_s hdr; bool vd = siemens_meas_setup(ifd, &hdr); long off[DIMS] = { 0 }; if (autoc) { long max[DIMS] = { [COIL_DIM] = 1000 }; long min[DIMS] = { 0 }; // min is always 0 adcs = 0; while (true) { if (-1 == siemens_bounds(vd, ifd, min, max)) break; debug_print_dims(DP_DEBUG3, DIMS, max); adcs++; } for (unsigned int i = 0; i < DIMS; i++) { off[i] = -min[i]; dims[i] = max[i] + off[i]; } debug_printf(DP_DEBUG2, "Dimensions: "); debug_print_dims(DP_DEBUG2, DIMS, dims); debug_printf(DP_DEBUG2, "Offset: "); debug_print_dims(DP_DEBUG2, DIMS, off); siemens_meas_setup(ifd, &hdr); // reset } long odims[DIMS]; md_copy_dims(DIMS, odims, dims); if (-1 != radial_lines) { // change output dims (must have identical layout!) odims[0] = 1; odims[1] = dims[0]; odims[2] = dims[1]; assert(1 == dims[2]); } complex float* out = create_cfl(argv[2], DIMS, odims); md_clear(DIMS, odims, out, CFL_SIZE); long adc_dims[DIMS]; md_select_dims(DIMS, READ_FLAG|COIL_FLAG, adc_dims, dims); void* buf = md_alloc(DIMS, adc_dims, CFL_SIZE); long mpi_slice = -1; while (adcs--) { long pos[DIMS] = { [0 ... DIMS - 1] = 0 }; if (-1 == siemens_adc_read(vd, ifd, linectr, partctr, dims, pos, buf)) { debug_printf(DP_WARN, "Stopping.\n"); break; } for (unsigned int i = 0; i < DIMS; i++) pos[i] += off[i]; if (mpi) { pos[SLICE_DIM] = mpi_slice; if ((0 == pos[TIME_DIM]) && (0 == pos[PHS1_DIM])) mpi_slice++; } debug_print_dims(DP_DEBUG1, DIMS, pos); if (!md_is_index(DIMS, pos, dims)) { debug_printf(DP_WARN, "Index out of bounds.\n"); continue; } md_copy_block(DIMS, pos, dims, out, adc_dims, buf, CFL_SIZE); } md_free(buf); unmap_cfl(DIMS, dims, out); return 0; } bart-0.5.00/src/var.c000066400000000000000000000021331353046746100142570ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Jon Tamir */ #include #include #include #include "num/multind.h" #include "num/init.h" #include "num/flpmath.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "bitmask "; static const char help_str[] = "Compute variance along selected dimensions specified by the {bitmask}"; int main_var(int argc, char* argv[]) { mini_cmdline(&argc, argv, 3, usage_str, help_str); num_init(); long flags = atoi(argv[1]); long idims[DIMS]; long odims[DIMS]; complex float* in = load_cfl(argv[2], DIMS, idims); md_select_dims(DIMS, ~flags, odims, idims); complex float* out = create_cfl(argv[3], DIMS, odims); md_zvar(DIMS, idims, flags, out, in); unmap_cfl(DIMS, idims, in); unmap_cfl(DIMS, odims, out); return 0; } bart-0.5.00/src/vec.c000066400000000000000000000017141353046746100142500ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" static const char usage_str[] = "val1 val2 ... valN name"; static const char help_str[] = "Create a vector of values.\n"; int main_vec(int argc, char* argv[]) { mini_cmdline(&argc, argv, -1, usage_str, help_str); num_init(); long dims[1] = { argc - 2 }; complex float* x = create_cfl(argv[argc - 1], 1, dims); for (int i = 0; i < argc - 2; i++) if (0 != parse_cfl(&x[i], argv[1 + i])) error("argument %d/%d is not a number: %s", i, argc - 2, argv[1 + i]); unmap_cfl(1, dims, x); return 0; } bart-0.5.00/src/version.c000066400000000000000000000030661353046746100151620ustar00rootroot00000000000000/* Copyright 2015-2016. Martin Uecker * Copyright 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015-2-16 Martin Uecker * 2016 Jonathan Tamir */ #include #include #include "misc/misc.h" #include "misc/opts.h" #include "misc/version.h" static const char usage_str[] = "[-h]"; static const char help_str[] = "Print BART version. The version string is of the form\n" "TAG or TAG-COMMITS-SHA as produced by 'git describe'. It\n" "specifies the last release (TAG), and (if git is used)\n" "the number of commits (COMMITS) since this release and\n" "the abbreviated hash of the last commit (SHA). If there\n" "are local changes '-dirty' is added at the end.\n"; int main_version(int argc, char* argv[]) { bool verbose = false; const struct opt_s opts[] = { OPT_SET('V', &verbose, "Output verbose info"), }; cmdline(&argc, argv, 0, 0, usage_str, help_str, ARRAY_SIZE(opts), opts); bart_printf("%s\n", bart_version); if (verbose) { #ifdef __GNUC__ bart_printf("GCC_VERSION=%s\n", __VERSION__); #endif bart_printf("CUDA="); #ifdef USE_CUDA bart_printf("1\n"); #else bart_printf("0\n"); #endif bart_printf("ACML="); #ifdef USE_ACML bart_printf("1\n"); #else bart_printf("0\n"); #endif bart_printf("FFTWTHREADS="); #ifdef FFTWTHREADS bart_printf("1\n"); #else bart_printf("0\n"); #endif } return 0; } bart-0.5.00/src/walsh.c000066400000000000000000000035661353046746100146200ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2015-2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013-2016 Martin Uecker */ #include #include #include "misc/mmio.h" #include "misc/misc.h" #include "misc/mri.h" #include "misc/opts.h" #include "misc/debug.h" #include "num/multind.h" #include "num/fft.h" #include "calib/walsh.h" static const char usage_str[] = " "; static const char help_str[] = "Estimate coil sensitivities using walsh method (use with ecaltwo)."; int main_walsh(int argc, char* argv[]) { long bsize[3] = { 20, 20, 20 }; long calsize[3] = { 24, 24, 24 }; const struct opt_s opts[] = { OPT_VEC3('r', &calsize, "cal_size", "Limits the size of the calibration region."), OPT_VEC3('R', &calsize, "", "()"), OPT_VEC3('b', &bsize, "block_size", "Block size."), OPT_VEC3('B', &bsize, "", "()"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); long dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, dims); assert((dims[0] == 1) || (calsize[0] < dims[0])); assert((dims[1] == 1) || (calsize[1] < dims[1])); assert((dims[2] == 1) || (calsize[2] < dims[2])); assert(1 == dims[MAPS_DIM]); long caldims[DIMS]; complex float* cal_data = extract_calib(caldims, calsize, dims, in_data, false); unmap_cfl(DIMS, dims, in_data); debug_printf(DP_INFO, "Calibration region %ldx%ldx%ld\n", caldims[0], caldims[1], caldims[2]); dims[COIL_DIM] = dims[COIL_DIM] * (dims[COIL_DIM] + 1) / 2; complex float* out_data = create_cfl(argv[2], DIMS, dims); walsh(bsize, dims, out_data, caldims, cal_data); debug_printf(DP_INFO, "Done.\n"); md_free(cal_data); unmap_cfl(DIMS, dims, out_data); return 0; } bart-0.5.00/src/wave.c000066400000000000000000000317041353046746100144370ustar00rootroot00000000000000/* Copyright 2015. The Regents of the University of California. * Copyright 2015. Martin Uecker. * Copyright 2018-2019. Massachusetts Institute of Technology. * * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2015 Berkin Bilgic * 2015 Martin Uecker * 2018-2019 Siddharth Iyer * * B Bilgic, BA Gagoski, SF Cauley, AP Fan, JR Polimeni, PE Grant, * LL Wald, and K Setsompop, Wave-CAIPI for highly accelerated 3D * imaging. Magn Reson Med (2014) doi: 10.1002/mrm.25347 */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "num/iovec.h" #include "num/ops_p.h" #include "num/ops.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "iter/iter.h" #include "iter/lsqr.h" #include "iter/misc.h" #include "linops/linop.h" #include "linops/fmac.h" #include "linops/someops.h" #include "linops/decompose_complex.h" #include "misc/debug.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "wavelet/wavthresh.h" #include "lowrank/lrthresh.h" static const char usage_str[] = " "; static const char help_str[] = "Perform a wave-caipi reconstruction.\n\n" "Conventions:\n" " * (sx, sy, sz) - Spatial dimensions.\n" " * wx - Extended FOV in READ_DIM due to\n" " wave's voxel spreading.\n" " * (nc, md) - Number of channels and ESPIRiT's \n" " extended-SENSE model operator\n" " dimensions (or # of maps).\n" "Expected dimensions:\n" " * maps - ( sx, sy, sz, nc, md)\n" " * wave - ( wx, sy, sz, 1, 1)\n" " * kspace - ( wx, sy, sz, nc, 1)\n" " * output - ( sx, sy, sz, 1, md)"; /* Helper function to print out operator dimensions. */ static void print_opdims(const struct linop_s* op) { const struct iovec_s* domain = linop_domain(op); const struct iovec_s* codomain = linop_codomain(op); debug_printf(DP_INFO, "\tDomain: "); debug_print_dims(DP_INFO, domain->N, domain->dims); debug_printf(DP_INFO, "\tCodomain: "); debug_print_dims(DP_INFO, codomain->N, codomain->dims); } /* ESPIRiT operator. */ static const struct linop_s* linop_espirit_create(long sx, long sy, long sz, long nc, long md, complex float* maps) { long max_dims[] = { [0 ... DIMS - 1] = 1}; max_dims[0] = sx; max_dims[1] = sy; max_dims[2] = sz; max_dims[3] = nc; max_dims[4] = md; const struct linop_s* E = linop_fmac_create(DIMS, max_dims, MAPS_FLAG, COIL_FLAG, ~(FFT_FLAGS|MAPS_FLAG|COIL_FLAG), maps); return E; } /* Resize operator. */ static const struct linop_s* Xlinop_reshape_create(long wx, long sx, long sy, long sz, long nc) { long input_dims[] = { [0 ... DIMS - 1] = 1}; input_dims[0] = sx; input_dims[1] = sy; input_dims[2] = sz; input_dims[3] = nc; long output_dims[DIMS]; md_copy_dims(DIMS, output_dims, input_dims); output_dims[0] = wx; struct linop_s* R = linop_resize_create(DIMS, output_dims, input_dims); return R; } /* Fx operator. */ static const struct linop_s* linop_fx_create(long wx, long sy, long sz, long nc) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; struct linop_s* Fx = linop_fft_create(DIMS, dims, READ_FLAG); return Fx; } /* Wave operator. */ static const struct linop_s* linop_wave_create(long wx, long sy, long sz, long nc, complex float* psf) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; struct linop_s* W = linop_cdiag_create(DIMS, dims, FFT_FLAGS, psf); return W; } /* Fyz operator. */ static const struct linop_s* linop_fyz_create(long wx, long sy, long sz, long nc) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; struct linop_s* Fyz = linop_fft_create(DIMS, dims, PHS1_FLAG|PHS2_FLAG); return Fyz; } /* Sampling operator. */ static const struct linop_s* linop_samp_create(long wx, long sy, long sz, long nc, complex float* mask) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; struct linop_s* M = linop_cdiag_create(DIMS, dims, FFT_FLAGS, mask); return M; } enum algo_t { CG, IST, FISTA }; int main_wave(int argc, char* argv[]) { double start_time = timestamp(); float lambda = 1E-5; int blksize = 8; int maxiter = 300; float step = 0.5; float tol = 1.E-3; bool wav = false; bool llr = false; bool fista = false; bool hgwld = false; float cont = 1; float eval = -1; int gpun = -1; bool dcx = false; const struct opt_s opts[] = { OPT_FLOAT( 'r', &lambda, "lambda", "Soft threshold lambda for wavelet or locally low rank."), OPT_INT( 'b', &blksize, "blkdim", "Block size for locally low rank."), OPT_INT( 'i', &maxiter, "mxiter", "Maximum number of iterations."), OPT_FLOAT( 's', &step, "stepsz", "Step size for iterative method."), OPT_FLOAT( 'c', &cont, "cntnu", "Continuation value for IST/FISTA."), OPT_FLOAT( 't', &tol, "toler", "Tolerance convergence condition for iterative method."), OPT_FLOAT( 'e', &eval, "eigvl", "Maximum eigenvalue of normal operator, if known."), OPT_INT( 'g', &gpun, "gpunm", "GPU device number."), OPT_SET( 'f', &fista, "Reconstruct using FISTA instead of IST."), OPT_SET( 'H', &hgwld, "Use hogwild in IST/FISTA."), OPT_SET( 'v', &dcx, "Split result to real and imaginary components."), OPT_SET( 'w', &wav, "Use wavelet."), OPT_SET( 'l', &llr, "Use locally low rank across the real and imaginary components."), }; cmdline(&argc, argv, 4, 4, usage_str, help_str, ARRAY_SIZE(opts), opts); debug_printf(DP_INFO, "Loading data... "); long maps_dims[DIMS]; complex float* maps = load_cfl(argv[1], DIMS, maps_dims); long wave_dims[DIMS]; complex float* wave = load_cfl(argv[2], DIMS, wave_dims); long kspc_dims[DIMS]; complex float* kspc = load_cfl(argv[3], DIMS, kspc_dims); debug_printf(DP_INFO, "Done.\n"); if (gpun >= 0) num_init_gpu_device(gpun); else num_init(); int wx = wave_dims[0]; int sx = maps_dims[0]; int sy = maps_dims[1]; int sz = maps_dims[2]; int nc = maps_dims[3]; int md = maps_dims[4]; long recon_dims[] = { [0 ... DIMS - 1] = 1 }; recon_dims[0] = sx; recon_dims[1] = sy; recon_dims[2] = sz; recon_dims[4] = md; recon_dims[8] = dcx ? 2 : 1; debug_printf(DP_INFO, "FFTMOD maps and kspc... "); fftmod(DIMS, kspc_dims, FFT_FLAGS, kspc, kspc); fftmod(DIMS, maps_dims, FFT_FLAGS, maps, maps); debug_printf(DP_INFO, "Done.\n"); debug_printf(DP_INFO, "Estimating sampling mask... "); long mask_dims[] = { [0 ... DIMS - 1] = 1 }; mask_dims[0] = wx; mask_dims[1] = sy; mask_dims[2] = sz; complex float* mask = md_calloc(DIMS, mask_dims, CFL_SIZE); estimate_pattern(DIMS, kspc_dims, ~FFT_FLAGS, mask, kspc); debug_printf(DP_INFO, "Done.\n"); debug_printf(DP_INFO, "Creating linear operators:\n"); double t1; double t2; t1 = timestamp(); const struct linop_s* E = linop_espirit_create(sx, sy, sz, nc, md, maps); t2 = timestamp(); debug_printf(DP_INFO, "\tE: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* R = Xlinop_reshape_create(wx, sx, sy, sz, nc); t2 = timestamp(); debug_printf(DP_INFO, "\tR: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* Fx = linop_fx_create(wx, sy, sz, nc); t2 = timestamp(); debug_printf(DP_INFO, "\tFx: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* W = linop_wave_create(wx, sy, sz, nc, wave); t2 = timestamp(); debug_printf(DP_INFO, "\tW: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* Fyz = linop_fyz_create(wx, sy, sz, nc); t2 = timestamp(); debug_printf(DP_INFO, "\tFyz: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* M = linop_samp_create(wx, sy, sz, nc, mask); t2 = timestamp(); debug_printf(DP_INFO, "\tM: %f seconds.\n", t2 - t1); debug_printf(DP_INFO, "Forward linear operator information:\n"); struct linop_s* A = linop_chain_FF(linop_chain_FF(linop_chain_FF(linop_chain_FF(linop_chain_FF( E, R), Fx), W), Fyz), M); if (dcx) { debug_printf(DP_INFO, "\tSplitting result into real and imaginary components.\n"); struct linop_s* tmp = A; struct linop_s* dcxop = linop_decompose_complex_create(DIMS, ITER_DIM, linop_domain(A)->dims); A = linop_chain_FF(dcxop, tmp); } print_opdims(A); if (eval < 0) #ifdef USE_CUDA eval = (gpun >= 0) ? estimate_maxeigenval_gpu(A->normal) : estimate_maxeigenval(A->normal); #else eval = estimate_maxeigenval(A->normal); #endif debug_printf(DP_INFO, "\tMax eval: %.2e\n", eval); step /= eval; debug_printf(DP_INFO, "Normalizing kspace... "); float norm = md_znorm(DIMS, kspc_dims, kspc); md_zsmul(DIMS, kspc_dims, kspc, kspc, 1. / norm); debug_printf(DP_INFO, "Done.\n"); const struct operator_p_s* T = NULL; long blkdims[MAX_LEV][DIMS]; long minsize[] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(sx, 16); minsize[1] = MIN(sy, 16); minsize[2] = MIN(sz, 16); unsigned int WAVFLAG = (sx > 1) * READ_FLAG | (sy > 1) * PHS1_FLAG | (sz > 2) * PHS2_FLAG; enum algo_t algo = CG; if ((wav) || (llr)) { algo = (fista) ? FISTA : IST; if (wav) { debug_printf(DP_INFO, "Creating wavelet threshold operator... "); T = prox_wavelet_thresh_create(DIMS, recon_dims, WAVFLAG, 0u, minsize, lambda, true); debug_printf(DP_INFO, "Done.\n"); } else { debug_printf(DP_INFO, "Creating locally low rank threshold operator across real-imag dimension... "); llr_blkdims(blkdims, ~ITER_FLAG, recon_dims, blksize); T = lrthresh_create(recon_dims, true, ~ITER_FLAG, (const long (*)[])blkdims, lambda, false, false, false); } debug_printf(DP_INFO, "Done.\n"); } italgo_fun2_t italgo = iter2_call_iter; struct iter_call_s iter2_data; SET_TYPEID(iter_call_s, &iter2_data); iter_conf* iconf = CAST_UP(&iter2_data); struct iter_conjgrad_conf cgconf = iter_conjgrad_defaults; struct iter_fista_conf fsconf = iter_fista_defaults; struct iter_ist_conf isconf = iter_ist_defaults; switch(algo) { case IST: debug_printf(DP_INFO, "Using IST.\n"); debug_printf(DP_INFO, "\tLambda: %0.2e\n", lambda); debug_printf(DP_INFO, "\tMaximum iterations: %d\n", maxiter); debug_printf(DP_INFO, "\tStep size: %0.2e\n", step); debug_printf(DP_INFO, "\tHogwild: %d\n", (int) hgwld); debug_printf(DP_INFO, "\tTolerance: %0.2e\n", tol); debug_printf(DP_INFO, "\tContinuation: %0.2e\n", cont); isconf = iter_ist_defaults; isconf.step = step; isconf.maxiter = maxiter; isconf.tol = tol; isconf.continuation = cont; isconf.hogwild = hgwld; iter2_data.fun = iter_ist; iter2_data._conf = CAST_UP(&isconf); break; case FISTA: debug_printf(DP_INFO, "Using FISTA.\n"); debug_printf(DP_INFO, "\tLambda: %0.2e\n", lambda); debug_printf(DP_INFO, "\tMaximum iterations: %d\n", maxiter); debug_printf(DP_INFO, "\tStep size: %0.2e\n", step); debug_printf(DP_INFO, "\tHogwild: %d\n", (int) hgwld); debug_printf(DP_INFO, "\tTolerance: %0.2e\n", tol); debug_printf(DP_INFO, "\tContinuation: %0.2e\n", cont); fsconf = iter_fista_defaults; fsconf.maxiter = maxiter; fsconf.step = step; fsconf.hogwild = hgwld; fsconf.tol = tol; fsconf.continuation = cont; iter2_data.fun = iter_fista; iter2_data._conf = CAST_UP(&fsconf); break; default: case CG: debug_printf(DP_INFO, "Using CG.\n"); debug_printf(DP_INFO, "\tMaximum iterations: %d\n", maxiter); debug_printf(DP_INFO, "\tTolerance: %0.2e\n", tol); cgconf = iter_conjgrad_defaults; cgconf.maxiter = maxiter; cgconf.l2lambda = 0; cgconf.tol = tol; iter2_data.fun = iter_conjgrad; iter2_data._conf = CAST_UP(&cgconf); break; } debug_printf(DP_INFO, "Reconstruction... "); complex float* recon = create_cfl(argv[4], DIMS, recon_dims); struct lsqr_conf lsqr_conf = { 0., gpun >= 0 }; double recon_start = timestamp(); const struct operator_p_s* J = lsqr2_create(&lsqr_conf, italgo, iconf, NULL, A, NULL, 1, &T, NULL, NULL); operator_p_apply(J, 1., DIMS, recon_dims, recon, DIMS, kspc_dims, kspc); double recon_end = timestamp(); debug_printf(DP_INFO, "Done.\nReconstruction time: %f seconds.\n", recon_end - recon_start); debug_printf(DP_INFO, "Cleaning up and saving result... "); operator_p_free(J); linop_free(A); md_free(mask); unmap_cfl(DIMS, maps_dims, maps); unmap_cfl(DIMS, wave_dims, wave); unmap_cfl(DIMS, kspc_dims, kspc); unmap_cfl(DIMS, recon_dims, recon); debug_printf(DP_INFO, "Done.\n"); double end_time = timestamp(); debug_printf(DP_INFO, "Total time: %f seconds.\n", end_time - start_time); return 0; } bart-0.5.00/src/wavelet.c000066400000000000000000000036631353046746100151470ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include #include #include "num/flpmath.h" #include "num/multind.h" #include "num/iovec.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/opts.h" #include "linops/linop.h" #include "linops/waveop.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "flags [dims] "; static const char help_str[] = "Perform wavelet transform."; int main_wavelet(int argc, char* argv[]) { bool adj = false; const struct opt_s opts[] = { OPT_SET('a', &adj, "adjoint (specify dims)"), }; cmdline(&argc, argv, 3, 100, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); unsigned int flags = atof(argv[1]); unsigned int n = adj ? bitcount(flags) : 0; assert((int)n + 3 == argc - 1); const unsigned int N = DIMS; long idims[N]; complex float* idata = load_cfl(argv[n + 2], N, idims); long dims[N]; md_copy_dims(N, dims, idims); if (adj) { unsigned int j = 0; for (unsigned int i = 0; i < N; i++) if (MD_IS_SET(flags, i)) dims[i] = atoi(argv[j++ + 2]); assert(j == n); } long minsize[N]; for (unsigned int i = 0; i < N; i++) minsize[i] = MD_IS_SET(flags, i) ? 16 : dims[i]; long strs[N]; md_calc_strides(N, strs, dims, CFL_SIZE); const struct linop_s* w = linop_wavelet_create(N, flags, dims, strs, minsize, false); long odims[N]; md_copy_dims(N, odims, (adj ? linop_domain : linop_codomain)(w)->dims); complex float* odata = create_cfl(argv[n + 3], N, odims); (adj ? linop_adjoint : linop_forward)(w, N, odims, odata, N, idims, idata); linop_free(w); unmap_cfl(N, idims, idata); unmap_cfl(N, odims, odata); return 0; } bart-0.5.00/src/wavelet/000077500000000000000000000000001353046746100147735ustar00rootroot00000000000000bart-0.5.00/src/wavelet/wavelet.c000066400000000000000000000476371353046746100166270ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Frank Ong * 2013-2017 Martin Uecker */ /* * md_*-based multi-dimensional wavelet implementation * * - 3 levels (1d, md, md-hierarchical) * - all higher-level code should work for GPU as well * * Bugs: * * - GPU version is not optimized * - memory use could possible be reduced * * Missing: * * - different boundary conditions * (symmetric, periodic, zero) */ #include #include #include #include #include #include "misc/misc.h" #include "misc/debug.h" #include "num/flpmath.h" #include "num/multind.h" #include "num/ops.h" #ifdef USE_CUDA #include "num/gpuops.h" #include "wavelet/wl3-cuda.h" #endif #include "wavelet.h" // layer 1 - 1-dimensional wavelet transform static unsigned int bandsize(unsigned int imsize, unsigned int flen) { return (imsize + flen - 1) / 2; } static complex float* access(const long str[3], complex float* x, long i, long j, long k) { return (void*)x + str[2] * i + str[1] * j + str[0] * k; } static const complex float* caccess(const long str[3], const complex float* x, long i, long j, long k) { return (const void*)x + str[2] * i + str[1] * j + str[0] * k; } static int coord(int l, int x, int flen, int k) { int n = 2 * l + 1 - (flen - 1) + k; if (n < 0) n = -n - 1; if (n >= x) n = x - 1 - (n - x); return n; } static void wavelet_down3(const long dims[3], const long out_str[3], complex float* out, const long in_str[3], const complex float* in, unsigned int flen, const float filter[flen]) { #pragma omp parallel for collapse(3) for (unsigned int i = 0; i < dims[2]; i++) for (unsigned int j = 0; j < bandsize(dims[1], flen); j++) for (unsigned int k = 0; k < dims[0]; k++) { *access(out_str, out, i, j, k) = 0.; for (unsigned int l = 0; l < flen; l++) { int n = coord(j, dims[1], flen, l); *access(out_str, out, i, j, k) += *(caccess(in_str, in, i, n, k)) * filter[flen - l - 1]; } } } static void wavelet_up3(const long dims[3], const long out_str[3], complex float* out, const long in_str[3], const complex float* in, unsigned int flen, const float filter[flen]) { // md_clear2(3, dims, out_str, out, CFL_SIZE); #pragma omp parallel for collapse(3) for (unsigned int i = 0; i < dims[2]; i++) for (unsigned int j = 0; j < dims[1]; j++) for (unsigned int k = 0; k < dims[0]; k++) { // *access(out_str, out, i, j, k) = 0.; for (unsigned int l = ((j + flen / 2 - 0) - (flen - 1)) % 2; l < flen; l += 2) { int n = ((j + flen / 2 - 0) - (flen - 1) + l) / 2; if ((0 <= n) && ((unsigned int)n < bandsize(dims[1], flen))) *access(out_str, out, i, j, k) += *caccess(in_str, in, i, n, k) * filter[flen - l - 1]; } } } void fwt1(unsigned int N, unsigned int d, const long dims[N], const long ostr[N], complex float* low, complex float* hgh, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen]) { debug_printf(DP_DEBUG4, "fwt1: %d/%d\n", d, N); debug_print_dims(DP_DEBUG4, N, dims); assert(dims[d] >= 2); long odims[N]; md_copy_dims(N, odims, dims); odims[d] = bandsize(dims[d], flen); debug_print_dims(DP_DEBUG4, N, odims); long o = d + 1; long u = N - o; // 0 1 2 3 4 5 6|7 // --d-- * --u--|N // ---o--- assert(d == md_calc_blockdim(d, dims + 0, istr + 0, CFL_SIZE)); assert(u == md_calc_blockdim(u, dims + o, istr + o, CFL_SIZE * md_calc_size(o, dims))); assert(d == md_calc_blockdim(d, odims + 0, ostr + 0, CFL_SIZE)); assert(u == md_calc_blockdim(u, odims + o, ostr + o, CFL_SIZE * md_calc_size(o, odims))); // merge dims long wdims[3] = { md_calc_size(d, dims), dims[d], md_calc_size(u, dims + o) }; long wistr[3] = { CFL_SIZE, istr[d], CFL_SIZE * md_calc_size(o, dims) }; long wostr[3] = { CFL_SIZE, ostr[d], CFL_SIZE * md_calc_size(o, odims) }; #ifdef USE_CUDA if (cuda_ondevice(in)) { assert(cuda_ondevice(low)); assert(cuda_ondevice(hgh)); float* flow = md_gpu_move(1, MD_DIMS(flen), filter[0][0], FL_SIZE); float* fhgh = md_gpu_move(1, MD_DIMS(flen), filter[0][1], FL_SIZE); wl3_cuda_down3(wdims, wostr, low, wistr, in, flen, flow); wl3_cuda_down3(wdims, wostr, hgh, wistr, in, flen, fhgh); md_free(flow); md_free(fhgh); return; } #endif // no clear needed wavelet_down3(wdims, wostr, low, wistr, in, flen, filter[0][0]); wavelet_down3(wdims, wostr, hgh, wistr, in, flen, filter[0][1]); } void iwt1(unsigned int N, unsigned int d, const long dims[N], const long ostr[N], complex float* out, const long istr[N], const complex float* low, const complex float* hgh, const long flen, const float filter[2][2][flen]) { debug_printf(DP_DEBUG4, "ifwt1: %d/%d\n", d, N); debug_print_dims(DP_DEBUG4, N, dims); assert(dims[d] >= 2); long idims[N]; md_copy_dims(N, idims, dims); idims[d] = bandsize(dims[d], flen); debug_print_dims(DP_DEBUG4, N, idims); long o = d + 1; long u = N - o; // 0 1 2 3 4 5 6|7 // --d-- * --u--|N // ---o--- assert(d == md_calc_blockdim(d, dims + 0, ostr + 0, CFL_SIZE)); assert(u == md_calc_blockdim(u, dims + o, ostr + o, CFL_SIZE * md_calc_size(o, dims))); assert(d == md_calc_blockdim(d, idims + 0, istr + 0, CFL_SIZE)); assert(u == md_calc_blockdim(u, idims + o, istr + o, CFL_SIZE * md_calc_size(o, idims))); long wdims[3] = { md_calc_size(d, dims), dims[d], md_calc_size(u, dims + o) }; long wistr[3] = { CFL_SIZE, istr[d], CFL_SIZE * md_calc_size(o, idims) }; long wostr[3] = { CFL_SIZE, ostr[d], CFL_SIZE * md_calc_size(o, dims) }; md_clear(3, wdims, out, CFL_SIZE); // we cannot clear because we merge outputs #ifdef USE_CUDA if (cuda_ondevice(out)) { assert(cuda_ondevice(low)); assert(cuda_ondevice(hgh)); float* flow = md_gpu_move(1, MD_DIMS(flen), filter[1][0], FL_SIZE); float* fhgh = md_gpu_move(1, MD_DIMS(flen), filter[1][1], FL_SIZE); wl3_cuda_up3(wdims, wostr, out, wistr, low, flen, flow); wl3_cuda_up3(wdims, wostr, out, wistr, hgh, flen, fhgh); md_free(flow); md_free(fhgh); return; } #endif wavelet_up3(wdims, wostr, out, wistr, low, flen, filter[1][0]); wavelet_up3(wdims, wostr, out, wistr, hgh, flen, filter[1][1]); } // layer 2 - multi-dimensional wavelet transform static void wavelet_dims_r(unsigned int N, unsigned int n, unsigned int flags, long odims[2 * N], const long dims[N], const long flen) { if (MD_IS_SET(flags, n)) { odims[0 + n] = bandsize(dims[n], flen); odims[N + n] = 2; } if (n > 0) wavelet_dims_r(N, n - 1, flags, odims, dims, flen); } void wavelet_dims(unsigned int N, unsigned int flags, long odims[2 * N], const long dims[N], const long flen) { md_copy_dims(N, odims, dims); md_singleton_dims(N, odims + N); wavelet_dims_r(N, N - 1, flags, odims, dims, flen); } void fwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[2 * N], complex float* out, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen]) { long odims[2 * N]; wavelet_dims(N, flags, odims, dims, flen); assert(md_calc_size(2 * N, odims) >= md_calc_size(N, dims)); // FIXME one of these is unnecessary if we use the output complex float* tmpA = md_alloc_sameplace(2 * N, odims, CFL_SIZE, out); complex float* tmpB = md_alloc_sameplace(2 * N, odims, CFL_SIZE, out); long tidims[2 * N]; md_copy_dims(N, tidims, dims); md_singleton_dims(N, tidims + N); long tistrs[2 * N]; md_calc_strides(2 * N, tistrs, tidims, CFL_SIZE); long todims[2 * N]; md_copy_dims(2 * N, todims, tidims); long tostrs[2 * N]; // maybe we should push the randshift into lower levels //md_copy2(N, dims, tistrs, tmpA, istr, in, CFL_SIZE); md_circ_shift2(N, dims, shifts, tistrs, tmpA, istr, in, CFL_SIZE); for (unsigned int i = 0; i < N; i++) { if (MD_IS_SET(flags, i)) { todims[0 + i] = odims[0 + i]; todims[N + i] = odims[N + i]; md_calc_strides(2 * N, tostrs, todims, CFL_SIZE); fwt1(2 * N, i, tidims, tostrs, tmpB, (void*)tmpB + tostrs[N + i], tistrs, tmpA, flen, filter); md_copy_dims(2 * N, tidims, todims); md_copy_dims(2 * N, tistrs, tostrs); complex float* swap = tmpA; tmpA = tmpB; tmpB = swap; } } md_copy2(2 * N, todims, ostr, out, tostrs, tmpA, CFL_SIZE); md_free(tmpA); md_free(tmpB); } void iwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[N], complex float* out, const long istr[2 * N], const complex float* in, const long flen, const float filter[2][2][flen]) { long idims[2 * N]; wavelet_dims(N, flags, idims, dims, flen); assert(md_calc_size(2 * N, idims) >= md_calc_size(N, dims)); complex float* tmpA = md_alloc_sameplace(2 * N, idims, CFL_SIZE, out); complex float* tmpB = md_alloc_sameplace(2 * N, idims, CFL_SIZE, out); long tidims[2 * N]; md_copy_dims(2 * N, tidims, idims); long tistrs[2 * N]; md_calc_strides(2 * N, tistrs, tidims, CFL_SIZE); long todims[2 * N]; md_copy_dims(2 * N, todims, tidims); long tostrs[2 * N]; long ishifts[N]; for (unsigned int i = 0; i < N; i++) ishifts[i] = -shifts[i]; md_copy2(2 * N, tidims, tistrs, tmpA, istr, in, CFL_SIZE); for (int i = N - 1; i >= 0; i--) { // run backwards to maintain contigous blocks if (MD_IS_SET(flags, i)) { todims[0 + i] = dims[0 + i]; todims[N + i] = 1; md_calc_strides(2 * N, tostrs, todims, CFL_SIZE); iwt1(2 * N, i, todims, tostrs, tmpB, tistrs, tmpA, (void*)tmpA + tistrs[N + i], flen, filter); md_copy_dims(2 * N, tidims, todims); md_copy_dims(2 * N, tistrs, tostrs); complex float* swap = tmpA; tmpA = tmpB; tmpB = swap; } } //md_copy2(N, dims, ostr, out, tostrs, tmpA, CFL_SIZE); md_circ_shift2(N, dims, ishifts, ostr, out, tostrs, tmpA, CFL_SIZE); md_free(tmpA); md_free(tmpB); } // layer 3 - hierarchical multi-dimensional wavelet transform static long wavelet_filter_flags(unsigned int N, long flags, const long dims[N], const long min[N]) { for (unsigned int i = 0; i < N; i++) if (dims[i] < min[i]) // CHECK flags = MD_CLEAR(flags, i); return flags; } long wavelet_num_levels(unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen) { if (0 == flags) return 1; long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims, flen); return 1 + wavelet_num_levels(N, wavelet_filter_flags(N, flags, wdims, min), wdims, min, flen); } static long wavelet_coeffs_r(unsigned int levels, unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen) { long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims, flen); long coeffs = md_calc_size(N, wdims); long bands = md_calc_size(N, wdims + N); assert((0 == flags) == (0 == levels)); if (0 == flags) return bands * coeffs; return coeffs * (bands - 1) + wavelet_coeffs_r(levels - 1, N, wavelet_filter_flags(N, flags, wdims, min), wdims, min, flen); } long wavelet_coeffs(unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen) { unsigned int levels = wavelet_num_levels(N, flags, dims, min, flen); assert(levels > 0); return wavelet_coeffs_r(levels - 1, N, flags, dims, min, flen); } void wavelet_thresh(unsigned int N, float lambda, unsigned int flags, unsigned int jflags, const long shifts[N], const long dims[N], complex float* out, const complex float* in, const long minsize[N], long flen, const float filter[2][2][flen]) { assert(0 == (flags & jflags)); long wdims[N]; wavelet_coeffs2(N, flags, wdims, dims, minsize, flen); long wstr[N]; md_calc_strides(N, wstr, wdims, CFL_SIZE); complex float* tmp = md_alloc_sameplace(N, wdims, CFL_SIZE, out); long str[N]; md_calc_strides(N, str, dims, CFL_SIZE); fwt2(N, flags, shifts, wdims, wstr, tmp, dims, str, in, minsize, flen, filter); md_zsoftthresh(N, wdims, lambda, jflags, tmp, tmp); iwt2(N, flags, shifts, dims, str, out, wdims, wstr, tmp, minsize, flen, filter); md_free(tmp); } void wavelet_coeffs2(unsigned int N, unsigned int flags, long odims[N], const long dims[N], const long min[N], const long flen) { md_select_dims(N, ~flags, odims, dims); if (0 == flags) return; unsigned int levels = wavelet_num_levels(N, flags, dims, min, flen); assert(levels > 0); long wdims[N]; md_select_dims(N, flags, wdims, dims); // remove unmodified dims unsigned int b = ffs(flags) - 1; odims[b] = wavelet_coeffs_r(levels - 1, N, flags, wdims, min, flen); } static bool wavelet_check_dims(unsigned int N, unsigned int flags, const long dims[N], const long minsize[N]) { for (unsigned int i = 0; i < N; i++) if (MD_IS_SET(flags, i)) if ((minsize[i] <= 2) || (dims[i] < minsize[i])) return false; return true; } static void embed(unsigned int N, unsigned int flags, long ostr[N], const long dims[N], const long str[N]) { unsigned int b = ffs(flags) - 1; long dims1[N]; md_select_dims(N, flags, dims1, dims); md_calc_strides(N, ostr, dims1, str[b]); for (unsigned int i = 0; i < N; i++) if (!MD_IS_SET(flags, i)) ostr[i] = str[i]; } void fwt2(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], const long ostr[N], complex float* out, const long idims[N], const long istr[N], const complex float* in, const long minsize[N], long flen, const float filter[2][2][flen]) { assert(wavelet_check_dims(N, flags, idims, minsize)); if (0 == flags) { // note: recursion does *not* end here assert(md_check_compat(N, 0u, odims, idims)); md_copy2(N, idims, ostr, out, istr, in, CFL_SIZE); return; } // check output dimensions long odims2[N]; wavelet_coeffs2(N, flags, odims2, idims, minsize, flen); assert(md_check_compat(N, 0u, odims2, odims)); long wdims2[2 * N]; wavelet_dims(N, flags, wdims2, idims, flen); // only consider transform dims... long dims1[N]; md_select_dims(N, flags, dims1, idims); long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims1, flen); long level_coeffs = md_calc_size(2 * N, wdims); // ... which get embedded in dimension b unsigned int b = ffs(flags) - 1; long ostr2[2 * N]; md_calc_strides(2 * N, ostr2, wdims, ostr[b]); // merge with original strides for (unsigned int i = 0; i < N; i++) if (!MD_IS_SET(flags, i)) ostr2[i] = ostr[i]; assert(odims[b] >= level_coeffs); long offset = (odims[b] - level_coeffs) * (ostr[b] / CFL_SIZE); long bands = md_calc_size(N, wdims + N); long coeffs = md_calc_size(N, wdims + 0); debug_printf(DP_DEBUG4, "fwt2: flags:%d lcoeffs:%ld coeffs:%ld (space:%ld) bands:%ld str:%ld off:%ld\n", flags, level_coeffs, coeffs, odims2[b], bands, ostr[b], offset / istr[b]); // subtract coefficients in high band odims2[b] -= (bands - 1) * coeffs; assert(odims2[b] > 0); long shifts0[N]; for (unsigned int i = 0; i < N; i++) shifts0[i] = 0; unsigned int flags2 = wavelet_filter_flags(N, flags, wdims, minsize); assert((0 == offset) == (0u == flags2)); fwtN(N, flags, shifts, idims, ostr2, out + offset, istr, in, flen, filter); if (0 != flags2) { long odims3[N]; wavelet_coeffs2(N, flags2, odims3, wdims2, minsize, flen); long ostr3[N]; embed(N, flags, ostr3, odims3, ostr); fwt2(N, flags2, shifts0, odims3, ostr3, out, wdims2, ostr2, out + offset, minsize, flen, filter); } } void iwt2(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], const long ostr[N], complex float* out, const long idims[N], const long istr[N], const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]) { assert(wavelet_check_dims(N, flags, odims, minsize)); if (0 == flags) { // note: recursion does *not* end here assert(md_check_compat(N, 0u, odims, idims)); md_copy2(N, idims, ostr, out, istr, in, CFL_SIZE); return; } // check input dimensions long idims2[N]; wavelet_coeffs2(N, flags, idims2, odims, minsize, flen); assert(md_check_compat(N, 0u, idims2, idims)); long wdims2[2 * N]; wavelet_dims(N, flags, wdims2, odims, flen); // only consider transform dims... long dims1[N]; md_select_dims(N, flags, dims1, odims); long wdims[2 * N]; wavelet_dims(N, flags, wdims, dims1, flen); long level_coeffs = md_calc_size(2 * N, wdims); // ... which get embedded in dimension b unsigned int b = ffs(flags) - 1; long istr2[2 * N]; md_calc_strides(2 * N, istr2, wdims, istr[b]); // merge with original strides for (unsigned int i = 0; i < N; i++) if (!MD_IS_SET(flags, i)) istr2[i] = istr[i]; assert(idims[b] >= level_coeffs); long offset = (idims[b] - level_coeffs) * (istr[b] / CFL_SIZE); long bands = md_calc_size(N, wdims + N); long coeffs = md_calc_size(N, wdims + 0); // subtract coefficients in high band idims2[b] -= (bands - 1) * coeffs; assert(idims2[b] > 0); debug_printf(DP_DEBUG4, "ifwt2: flags:%d lcoeffs:%ld coeffs:%ld (space:%ld) bands:%ld str:%ld off:%ld\n", flags, level_coeffs, coeffs, idims2[b], bands, istr[b], offset / ostr[b]); // fix me we need temp storage complex float* tmp = md_alloc_sameplace(2 * N, wdims2, CFL_SIZE, out); long tstr[2 * N]; md_calc_strides(2 * N, tstr, wdims2, CFL_SIZE); md_copy2(2 * N, wdims2, tstr, tmp, istr2, in + offset, CFL_SIZE); long shifts0[N]; for (unsigned int i = 0; i < N; i++) shifts0[i] = 0; unsigned int flags2 = wavelet_filter_flags(N, flags, wdims, minsize); assert((0 == offset) == (0u == flags2)); if (0u != flags2) { long idims3[N]; wavelet_coeffs2(N, flags2, idims3, wdims2, minsize, flen); long istr3[N]; embed(N, flags, istr3, idims3, istr); iwt2(N, flags2, shifts0, wdims2, tstr, tmp, idims3, istr3, in, minsize, flen, filter); } iwtN(N, flags, shifts, odims, ostr, out, tstr, tmp, flen, filter); md_free(tmp); } void fwt(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], complex float* out, const long idims[N], const complex float* in, const long minsize[N], long flen, const float filter[2][2][flen]) { fwt2(N, flags, shifts, odims, MD_STRIDES(N, odims, CFL_SIZE), out, idims, MD_STRIDES(N, idims, CFL_SIZE), in, minsize, flen, filter); } void iwt(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], complex float* out, const long idims[N], const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]) { iwt2(N, flags, shifts, odims, MD_STRIDES(N, odims, CFL_SIZE), out, idims, MD_STRIDES(N, idims, CFL_SIZE), in, minsize, flen, filter); } const float wavelet_haar[2][2][2] = { { { +0.7071067811865475, +0.7071067811865475 }, { -0.7071067811865475, +0.7071067811865475 }, }, { { +0.7071067811865475, +0.7071067811865475 }, { +0.7071067811865475, -0.7071067811865475 }, }, }; const float wavelet_dau2[2][2][4] = { { { -0.1294095225512603, +0.2241438680420134, +0.8365163037378077, +0.4829629131445341 }, { -0.4829629131445341, +0.8365163037378077, -0.2241438680420134, -0.1294095225512603 }, }, { { +0.4829629131445341, +0.8365163037378077, +0.2241438680420134, -0.1294095225512603 }, { -0.1294095225512603, -0.2241438680420134, +0.8365163037378077, -0.4829629131445341 }, }, }; const float wavelet_cdf44[2][2][10] = { { { +0.00000000000000000, +0.03782845550726404 , -0.023849465019556843, -0.11062440441843718 , +0.37740285561283066, +0.85269867900889385, +0.37740285561283066 , -0.11062440441843718 , -0.023849465019556843, +0.03782845550726404 }, { +0.00000000000000000, -0.064538882628697058, +0.040689417609164058, +0.41809227322161724 , -0.7884856164055829, +0.41809227322161724, +0.040689417609164058, -0.064538882628697058, +0.00000000000000000 , +0.00000000000000000 }, }, { { +0.00000000000000000, -0.064538882628697058, -0.040689417609164058, +0.41809227322161724 , +0.7884856164055829, +0.41809227322161724, -0.040689417609164058, -0.064538882628697058, +0.000000000000000000, +0.00000000000000000 }, { +0.00000000000000000, -0.03782845550726404 , -0.023849465019556843, +0.11062440441843718 , +0.37740285561283066, -0.85269867900889385, +0.37740285561283066 , +0.11062440441843718 , -0.023849465019556843, -0.03782845550726404 }, }, }; bart-0.5.00/src/wavelet/wavelet.h000066400000000000000000000061011353046746100166110ustar00rootroot00000000000000/* Copyright 2014-2015. The Regents of the University of California. * Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. */ #include #include extern const float wavelet_haar[2][2][2]; extern const float wavelet_dau2[2][2][4]; extern const float wavelet_cdf44[2][2][10]; // layer 1 extern void fwt1(unsigned int N, unsigned int d, const long dims[N], const long ostr[N], complex float* low, complex float* hgh, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen]); extern void iwt1(unsigned int N, unsigned int d, const long dims[N], const long ostr[N], complex float* out, const long istr[N], const complex float* low, const complex float* hgh, const long flen, const float filter[2][2][flen]); // layer 2 extern void fwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[2 * N], complex float* out, const long istr[N], const complex float* in, const long flen, const float filter[2][2][flen]); extern void iwtN(unsigned int N, unsigned int flags, const long shifts[N], const long dims[N], const long ostr[N], complex float* out, const long istr[2 * N], const complex float* in, const long flen, const float filter[2][2][flen]); extern void wavelet_dims(unsigned int N, unsigned int flags, long odims[2 * N], const long dims[N], const long flen); // layer 3 extern void fwt(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], complex float* out, const long idims[N], const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]); extern void iwt(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], complex float* out, const long idims[N], const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]); extern long wavelet_num_levels(unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen); extern long wavelet_coeffs(unsigned int N, unsigned int flags, const long dims[N], const long min[N], const long flen); extern void wavelet_coeffs2(unsigned int N, unsigned int flags, long odims[N], const long dims[N], const long min[N], const long flen); extern void fwt2(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], const long ostr[N], complex float* out, const long idims[N], const long istr[N], const complex float* in, const long minsize[N], long flen, const float filter[2][2][flen]); extern void iwt2(unsigned int N, unsigned int flags, const long shifts[N], const long odims[N], const long ostr[N], complex float* out, const long idims[N], const long istr[N], const complex float* in, const long minsize[N], const long flen, const float filter[2][2][flen]); extern void wavelet_thresh(unsigned int N, float lambda, unsigned int flags, unsigned int jflags, const long shifts[N], const long dims[N], complex float* out, const complex float* in, const long minsize[N], long flen, const float filter[2][2][flen]); bart-0.5.00/src/wavelet/wavthresh.c000066400000000000000000000063521353046746100171600ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2013 Frank Ong * 2013-2019 Martin Uecker */ #define _GNU_SOURCE #include #include #include #include #include "misc/misc.h" #include "misc/types.h" #include "num/multind.h" #include "num/ops.h" #include "num/ops_p.h" #include "wavelet/wavelet.h" #include "wavthresh.h" struct wavelet_thresh_s { INTERFACE(operator_data_t); unsigned int N; const long* dims; const long* minsize; unsigned int flags; unsigned int jflags; float lambda; bool randshift; int rand_state; }; static DEF_TYPEID(wavelet_thresh_s); static int rand_lim(unsigned int* state, int limit) { int divisor = RAND_MAX / (limit + 1); int retval; do { retval = rand_r(state) / divisor; } while (retval > limit); return retval; } static void wavelet_thresh_apply(const operator_data_t* _data, float mu, complex float* out, const complex float* in) { const auto data = CAST_DOWN(wavelet_thresh_s, _data); long shift[data->N]; for (unsigned int i = 0; i < data->N; i++) shift[i] = 0; if (data->randshift) { for (unsigned int i = 0; i < data->N; i++) { if (MD_IS_SET(data->flags, i)) { int levels = wavelet_num_levels(data->N, MD_BIT(i), data->dims, data->minsize, 4); shift[i] = rand_lim((unsigned int*)&data->rand_state, 1 << levels); assert(shift[i] < data->dims[i]); } } } wavelet_thresh(data->N, data->lambda * mu, data->flags, data->jflags, shift, data->dims, out, in, data->minsize, 4, wavelet_dau2); } void wavthresh_rand_state_set(const struct operator_p_s* op, int x) { auto data = CAST_DOWN(wavelet_thresh_s, operator_p_get_data(op)); data->rand_state = x; } static void wavelet_thresh_del(const operator_data_t* _data) { const auto data = CAST_DOWN(wavelet_thresh_s, _data); xfree(data->dims); xfree(data->minsize); xfree(data); } /** * Proximal operator for l1-norm with Wavelet transform: f(x) = lambda || W x ||_1 * * @param N number of dimensions * @param dims dimensions of x * @param flags bitmask for Wavelet transform * @param jflags bitmask for joint thresholding * @param minsize minimium size of coarse Wavelet scale * @param lambda threshold parameter * @param randshift random shifting */ const struct operator_p_s* prox_wavelet_thresh_create(unsigned int N, const long dims[N], unsigned int flags, unsigned int jflags, const long minsize[N], float lambda, bool randshift) { PTR_ALLOC(struct wavelet_thresh_s, data); SET_TYPEID(wavelet_thresh_s, data); data->N = N; long (*ndims)[N] = TYPE_ALLOC(long[N]); md_copy_dims(N, (*ndims), dims); data->dims = *ndims; long (*nminsize)[N] = TYPE_ALLOC(long[N]); md_copy_dims(N, (*nminsize), minsize); data->minsize = *nminsize; data->flags = flags; data->jflags = jflags; data->lambda = lambda; data->randshift = randshift; data->rand_state = 1; return operator_p_create(N, dims, N, dims, CAST_UP(PTR_PASS(data)), wavelet_thresh_apply, wavelet_thresh_del); } bart-0.5.00/src/wavelet/wavthresh.h000066400000000000000000000004471353046746100171640ustar00rootroot00000000000000 #include extern const struct operator_p_s* prox_wavelet_thresh_create(unsigned int N, const long dims[N], unsigned int flags, unsigned int jflags, const long minsize[N], float lambda, bool randshift); extern void wavthresh_rand_state_set(const struct operator_p_s* op, int x); bart-0.5.00/src/wavelet/wl3-cuda.cu000066400000000000000000000072531353046746100167520ustar00rootroot00000000000000/* Copyright 2014. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2014 Martin Uecker */ #include #include #include #include #include #include "misc/misc.h" #include "wl3-cuda.h" #ifndef CFL_SIZE #define CFL_SIZE sizeof(_Complex float) #endif __device__ long Wdot(dim3 a, dim3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } __device__ dim3 Wpmuladd(dim3 a, dim3 b, dim3 c) { dim3 r(a.x * b.x + c.x, a.y * b.y + c.y, a.z * b.z + c.z); return r; } __device__ dim3 Wpmul(dim3 a, dim3 b) { dim3 r(a.x * b.x, a.y * b.y, a.z * b.z); return r; } __host__ __device__ int bandsize(unsigned int imsize, unsigned int flen) { return (imsize + flen - 1) / 2; } __host__ __device__ int coord(int l, int x, int flen, int k) { int n = 2 * l + 1 - (flen - 1) + k; if (n < 0) n = -n - 1; if (n >= x) n = x - 1 - (n - x); return n; } __global__ void kern_down3(dim3 dims, dim3 ostr, cuFloatComplex* out, dim3 istr, const cuFloatComplex* in, unsigned int flen, const float* filter) { dim3 ind = Wpmuladd(blockIdx, blockDim, threadIdx); if ((ind.x >= dims.x) || (ind.y >= bandsize(dims.y, flen)) || (ind.z >= dims.z)) return; cuFloatComplex y = make_cuFloatComplex(0., 0.); for (unsigned int l = 0; l < flen; l++) { int n = coord(ind.y, dims.y, flen, l); dim3 ac = ind; ac.y = n; y.x += in[Wdot(ac, istr)].x * filter[flen - l - 1]; y.y += in[Wdot(ac, istr)].y * filter[flen - l - 1]; } out[Wdot(ind, ostr)] = y; } __global__ void kern_up3(dim3 dims, dim3 ostr, cuFloatComplex* out, dim3 istr, const cuFloatComplex* in, unsigned int flen, const float* filter) { dim3 ind = Wpmuladd(blockIdx, blockDim, threadIdx); if ((ind.x >= dims.x) || (ind.y >= dims.y) || (ind.z >= dims.z)) return; // cuFloatComplex y = make_cuFloatComplex(0., 0.); cuFloatComplex y = out[Wdot(ind, ostr)]; for (unsigned int l = ((ind.y + flen / 2 - 0) - (flen - 1)) % 2; l < flen; l += 2) { int n = ((ind.y + flen / 2 - 0) - (flen - 1) + l) / 2; dim3 ac = ind; ac.y = n; if ((0 <= n) && ((unsigned int)n < bandsize(dims.y, flen))) { y.x += in[Wdot(ac, istr)].x * filter[flen - l - 1]; y.y += in[Wdot(ac, istr)].y * filter[flen - l - 1]; } } out[Wdot(ind, ostr)] = y; } // extern "C" size_t cuda_shared_mem; extern "C" void wl3_cuda_down3(const long dims[3], const long out_str[3], _Complex float* out, const long in_str[3], const _Complex float* in, unsigned int flen, const float filter[__VLA(flen)]) { dim3 dims3(dims[0], dims[1], dims[2]); dim3 ostrs(out_str[0] / CFL_SIZE, out_str[1] / CFL_SIZE, out_str[2] / CFL_SIZE); dim3 istrs(in_str[0] / CFL_SIZE, in_str[1] / CFL_SIZE, in_str[2] / CFL_SIZE); long d1 = bandsize(dims[1], flen); int T = 8; dim3 th(T, T, T); dim3 bl((dims[0] + T - 1) / T, (d1 + T - 1) / T, (dims[2] + T - 1) / T); kern_down3<<< bl, th >>>(dims3, ostrs, (cuFloatComplex*)out, istrs, (const cuFloatComplex*)in, flen, filter); } extern "C" void wl3_cuda_up3(const long dims[3], const long out_str[3], _Complex float* out, const long in_str[3], const _Complex float* in, unsigned int flen, const float filter[__VLA(flen)]) { dim3 dims3(dims[0], dims[1], dims[2]); dim3 ostrs(out_str[0] / CFL_SIZE, out_str[1] / CFL_SIZE, out_str[2] / CFL_SIZE); dim3 istrs(in_str[0] / CFL_SIZE, in_str[1] / CFL_SIZE, in_str[2] / CFL_SIZE); int T = 8; dim3 th(T, T, T); dim3 bl((dims[0] + T - 1) / T, (dims[1] + T - 1) / T, (dims[2] + T - 1) / T); kern_up3<<< bl, th >>>(dims3, ostrs, (cuFloatComplex*)out, istrs, (const cuFloatComplex*)in, flen, filter); } bart-0.5.00/src/wavelet/wl3-cuda.h000066400000000000000000000006711353046746100165670ustar00rootroot00000000000000 #include "misc/cppwrap.h" extern void wl3_cuda_down3(const long dims[3], const long out_str[3], _Complex float* out, const long in_str[3], const _Complex float* in, unsigned int flen, const float filter[__VLA(flen)]); extern void wl3_cuda_up3(const long dims[3], const long out_str[3], _Complex float* out, const long in_str[3], const _Complex float* in, unsigned int flen, const float filter[__VLA(flen)]); #include "misc/cppwrap.h" bart-0.5.00/src/wavepsf.c000066400000000000000000000117221353046746100151460ustar00rootroot00000000000000/* Copyright 2017-2018. Massachusetts Institute of Technology. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Siddharth Iyer * * Bilgic B, Gagoski BA, Cauley SF, Fan AP, Polimeni JR, Grant PE, Wald LL, Setsompop K. * Waveâ€CAIPI for highly accelerated 3D imaging. Magnetic resonance in medicine. * 2015 Jun 1;73(6):2152-62. */ #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "misc/debug.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" // Larmor frequency in Hertz per Gauss #ifndef LARMOR #define LARMOR 4257.56 #endif static const char usage_str[] = ""; static const char help_str[] = "Generate a wave PSF in hybrid space.\n" "- Assumes the first dimension is the readout dimension.\n" "- Only generates a 2 dimensional PSF.\n" "- Use reshape and fmac to generate a 3D PSF.\n\n" "3D PSF Example:\n" "bart wavepsf -x 768 -y 128 -r 0.1 -a 3000 -t 0.00001 -g 0.8 -s 17000 -n 6 wY\n" "bart wavepsf -c -x 768 -y 128 -r 0.1 -a 3000 -t 0.00001 -g 0.8 -s 17000 -n 6 wZ\n" "bart reshape 7 wZ 768 1 128 wZ wZ\n" "bart fmac wY wZ wYZ"; int main_wavepsf(int argc, char* argv[]) { // Spatial dimensions. int sx = 512; // Number of readout points. int sy = 128; // Number of phase encode points. float dy = 0.1; // Resolution in the phase encode direction in cm. // ADC parameters. int adc = 3000; // Readout duration in microseconds. float dt = 1e-5; // ADC sampling rate in seconds. // Gradient parameters. float gmax = 0.8; // Maximum gradient amplitude in Gauss per centimeter. float smax = 17000; // Maximum slew rate in Gauss per centimeter per second. // Wave parameters. int ncyc = 6; // Number of gradient sine-cycles. // Sine wave or cosine wave. bool cs = false; // Set to true to use a cosine gradient wave/ const struct opt_s opts[] = { OPT_SET( 'c', &cs, "Set to use a cosine gradient wave"), OPT_INT( 'x', &sx, "RO_dim", "Number of readout points"), OPT_INT( 'y', &sy, "PE_dim", "Number of phase encode points"), OPT_FLOAT('r', &dy, "PE_res", "Resolution of phase encode in cm"), OPT_INT( 'a', &adc, "ADC_T", "Readout duration in microseconds."), OPT_FLOAT('t', &dt, "ADC_dt", "ADC sampling rate in seconds"), OPT_FLOAT('g', &gmax, "gMax", "Maximum gradient amplitude in Gauss/cm"), OPT_FLOAT('s', &smax, "sMax", "Maximum gradient slew rate in Gauss/cm/second"), OPT_INT( 'n', &ncyc, "ncyc", "Number of cycles in the gradient wave"), }; cmdline(&argc, argv, 1, 1, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); assert(0 == adc % 10); // Scanners require ADC_duration to be a multiple of 10. int wavepoints = adc/10; // Number of points in the gradient wave. float T = wavepoints * dt/ncyc; // Time period of the sine wave. float w = 2 * M_PI/T; // Frequency in radians per second. /* Calculating the wave-amplitude to use. It is either slew limited or gradient amplitude limited. */ float gamp = (smax >= w * gmax) ? gmax : smax/w; float gwave[wavepoints]; for (int tdx = 0; tdx < wavepoints; tdx++) { gwave[tdx] = gamp * ((cs) ? cos(w * tdx * dt) : sin(w * tdx * dt)); } complex float phasepercm[wavepoints]; float prephase = -2 * M_PI * LARMOR * gamp/w; float cumsum = 0; for (int tdx = 0; tdx < wavepoints; tdx++) { phasepercm[tdx] = 2 * M_PI * LARMOR * (cumsum + gwave[tdx]/2.0) * dt + prephase; cumsum = cumsum + gwave[tdx]; } // Interpolate to sx via sinc interpolation const long wavepoint_dims[1] = {wavepoints}; const long interp_dims[1] = {sx}; complex float k_phasepercm[wavepoints]; fftuc(1, wavepoint_dims, 1, k_phasepercm, phasepercm); complex float k_phasepercm_interp[sx]; md_resize_center(1, interp_dims, k_phasepercm_interp, wavepoint_dims, k_phasepercm, sizeof(complex float)); complex float phasepercm_interp_complex[sx]; ifftuc(1, interp_dims, 1, phasepercm_interp_complex, k_phasepercm_interp); complex float phasepercm_interp_real[sx]; md_zreal(1, interp_dims, phasepercm_interp_real, phasepercm_interp_complex); complex float phasepercm_interp[sx]; float scale = sqrt((float) sx/wavepoints); md_zsmul(1, interp_dims, phasepercm_interp, phasepercm_interp_real, scale); complex float psf[sy][sx]; int midy = sy/2; complex float phase[sx]; float val; for (int ydx = 0; ydx < sy; ydx++) { val = -dy * (ydx - midy); md_zsmul(1, interp_dims, phase, phasepercm_interp, val); md_zexpj(1, interp_dims, psf[ydx], phase); } const long psf_dims[3] = {sx, sy, 1}; complex float* psf_cfl = create_cfl(argv[1], 3, psf_dims); md_copy(3, psf_dims, psf_cfl, psf, sizeof(complex float)); unmap_cfl(3, psf_dims, psf_cfl); return 0; } bart-0.5.00/src/whiten.c000066400000000000000000000115241353046746100147710ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Jon Tamir */ #include #include #include #include "num/multind.h" #include "num/init.h" #include "num/flpmath.h" #include "num/lapack.h" #include "misc/mri.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "misc/debug.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " [] []"; static const char help_str[] = "Apply multi-channel noise pre-whitening on using noise data .\n" "Optionally output whitening matrix and noise covariance matrix"; static void whiten(const long dims[DIMS], complex float* out, const long mat_dims[DIMS], const complex float* mat, const complex float* in) { long trp_dims[DIMS]; md_transpose_dims(DIMS, COIL_DIM, MAPS_DIM, trp_dims, dims); md_zmatmul(DIMS, trp_dims, out, mat_dims, mat, dims, in); } /* * Calculate noise covariance matrix. Assumes noise is zero-mean */ static void calc_covar(const long mat_dims[DIMS], complex float* covar, const long noise_dims[DIMS], const complex float* ndata) { long trp_dims[DIMS]; md_transpose_dims(DIMS, COIL_DIM, MAPS_DIM, trp_dims, noise_dims); md_zmatmulc(DIMS, mat_dims, covar, trp_dims, ndata, noise_dims, ndata); md_zsmul(DIMS, mat_dims, covar, covar, 1. / (noise_dims[READ_DIM] - 1)); } /* * Calculate noise whitening matrix W = inv(L), where N = L * L^H is the Cholesky decomposition of noise N */ static void calc_optmat(const long mat_dims[DIMS], complex float* optmat, const complex float* covar) { long N = mat_dims[COIL_DIM]; complex float* chol = md_alloc(DIMS, mat_dims, CFL_SIZE); md_copy(DIMS, mat_dims, chol, covar, CFL_SIZE); lapack_cholesky_lower(N, MD_CAST_ARRAY2(complex float, DIMS, mat_dims, chol, COIL_DIM, MAPS_DIM)); lapack_trimat_inverse_lower(N, MD_CAST_ARRAY2(complex float, DIMS, mat_dims, chol, COIL_DIM, MAPS_DIM)); for (int i = 0; i < N; i++) for (int j = 0; j < i; j++) chol[i * N + j] = 0.; md_transpose(DIMS, COIL_DIM, MAPS_DIM, mat_dims, optmat, mat_dims, chol, CFL_SIZE); md_free(chol); } int main_whiten(int argc, char* argv[]) { const char* optmat_file = NULL; const char* covar_file = NULL; bool normalize = false; const struct opt_s opts[] = { OPT_STRING('o', &optmat_file, "", "use external whitening matrix "), OPT_STRING('c', &covar_file, "", "use external noise covariance matrix "), OPT_SET('n', &normalize, "normalize variance to 1 using noise data "), }; cmdline(&argc, argv, 3, 5, usage_str, help_str, ARRAY_SIZE(opts), opts); int num_args = argc - 1; num_init(); long dims[DIMS]; long noise_dims[DIMS]; long mat_dims[DIMS]; complex float* idata = load_cfl(argv[1], DIMS, dims); complex float* ndata = load_cfl(argv[2], DIMS, noise_dims); complex float* odata = create_cfl(argv[3], DIMS, dims); md_select_dims(DIMS, COIL_FLAG, mat_dims, noise_dims); mat_dims[MAPS_DIM] = mat_dims[COIL_DIM]; complex float* optmat_in = NULL; complex float* optmat_out = NULL; complex float* covar_in = NULL; complex float* covar_out = NULL; if (num_args > 3) optmat_out = create_cfl(argv[4], DIMS, mat_dims); else optmat_out = anon_cfl(NULL, DIMS, mat_dims); if (num_args > 4) covar_out = create_cfl(argv[5], DIMS, mat_dims); else covar_out = anon_cfl(NULL, DIMS, mat_dims); if (NULL != covar_file) { covar_in = load_cfl(covar_file, DIMS, mat_dims); md_copy(DIMS, mat_dims, covar_out, covar_in, CFL_SIZE); unmap_cfl(DIMS, mat_dims, covar_in); } else calc_covar(mat_dims, covar_out, noise_dims, ndata); if (NULL != optmat_file) { optmat_in = load_cfl(optmat_file, DIMS, mat_dims); md_copy(DIMS, mat_dims, optmat_out, optmat_in, CFL_SIZE); unmap_cfl(DIMS, mat_dims, optmat_in); } else { calc_optmat(mat_dims, optmat_out, covar_out); } whiten(dims, odata, mat_dims, optmat_out, idata); if (normalize) { long std_dims[DIMS]; md_singleton_dims(DIMS, std_dims); complex float* nwhite = md_alloc(DIMS, noise_dims, CFL_SIZE); complex float* nstdev = md_alloc(DIMS, std_dims, CFL_SIZE); // get scale factor by whitening the noise data and taking stdev whiten(noise_dims, nwhite, mat_dims, optmat_out, ndata); md_zstd(DIMS, noise_dims, ~0, nstdev, nwhite); float stdev = md_zasum(DIMS, std_dims, nstdev); md_zsmul(DIMS, dims, odata, odata, 1. / stdev); debug_printf(DP_DEBUG1, "standard deviation scaling: %.6e\n", stdev); md_free(nwhite); md_free(nstdev); } unmap_cfl(DIMS, dims, idata); unmap_cfl(DIMS, noise_dims, ndata); unmap_cfl(DIMS, dims, odata); unmap_cfl(DIMS, mat_dims, optmat_out); unmap_cfl(DIMS, mat_dims, covar_out); return 0; } bart-0.5.00/src/window.c000066400000000000000000000022661353046746100150050ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Jon Tamir */ #include #include #include "num/multind.h" #include "num/filter.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = "flags "; static const char help_str[] = "Apply Hamming (Hann) window to along dimensions specified by flags"; int main_window(int argc, char* argv[]) { bool hamming = true; const struct opt_s opts[] = { OPT_CLEAR('H', &hamming, "Hann window"), }; cmdline(&argc, argv, 3, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long dims[DIMS]; long flags = atoi(argv[1]); complex float* in_data = load_cfl(argv[2], DIMS, dims); complex float* out_data = create_cfl(argv[3], DIMS, dims); (hamming ? md_zhamming : md_zhann)(DIMS, dims, flags, out_data, in_data); unmap_cfl(DIMS, dims, in_data); unmap_cfl(DIMS, dims, out_data); return 0; } bart-0.5.00/src/wshfl.c000066400000000000000000001135531353046746100146230ustar00rootroot00000000000000/* Copyright 2018-2019. Massachusetts Institute of Technology. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018-2019 Siddharth Iyer * * Tamir J, Uecker M, Chen W, Lai P, Alley MT, Vasanawala SS, Lustig M. * T2 shuffling: Sharp, multicontrast, volumetric fast spinâ€echo imaging. * Magnetic resonance in medicine. 2017 Jan 1;77(1):180-95. * * B Bilgic, BA Gagoski, SF Cauley, AP Fan, JR Polimeni, PE Grant, * LL Wald, and K Setsompop, Wave-CAIPI for highly accelerated 3D * imaging. Magn Reson Med (2014) doi: 10.1002/mrm.25347 * * Iyer S, Bilgic B, Setsompop K. * Faster T2 shuffling with Wave. * Presented in the session: "Signal Encoding and Decoding" at ISMRM 2018. * https://www.ismrm.org/18/program_files/O67.htm */ #include #include #include #ifdef _OPENMP #include #endif #include "num/multind.h" #include "num/flpmath.h" #include "num/fft.h" #include "num/init.h" #include "num/iovec.h" #include "num/ops.h" #include "num/ops_p.h" #ifdef USE_CUDA #include "num/gpuops.h" #endif #include "iter/iter.h" #include "iter/lsqr.h" #include "iter/misc.h" #include "linops/linop.h" #include "linops/fmac.h" #include "linops/someops.h" #include "linops/decompose_complex.h" #include "misc/debug.h" #include "misc/mri.h" #include "misc/utils.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #include "wavelet/wavthresh.h" #include "lowrank/lrthresh.h" static const char usage_str[] = " "; static const char help_str[] = "Perform a wave-shuffling reconstruction.\n\n" "Conventions:\n" " * (sx, sy, sz) - Spatial dimensions.\n" " * wx - Extended FOV in READ_DIM due to\n" " wave's voxel spreading.\n" " * (nc, md) - Number of channels and ESPIRiT's \n" " extended-SENSE model operator\n" " dimensions (or # of maps).\n" " * (tf, tk) - Turbo-factor and the rank\n" " of the temporal basis used in\n" " shuffling.\n" " * ntr - Number of TRs, or the number of\n" " (ky, kz) points acquired of one\n" " echo image.\n" " * n - Total number of (ky, kz) points\n" " acquired. This is equal to the\n" " product of ntr and tf.\n\n" "Descriptions:\n" " * reorder is an (n by 3) index matrix such that\n" " [ky, kz, t] = reorder(i, :) represents the\n" " (ky, kz) kspace position of the readout line\n" " acquired at echo number (t), and 0 <= ky < sy,\n" " 0 <= kz < sz, 0 <= t < tf).\n" " * table is a (wx by nc by n) matrix such that\n" " table(:, :, k) represents the kth multichannel\n" " kspace line.\n\n" "Expected dimensions:\n" " * maps - ( sx, sy, sz, nc, md, 1, 1)\n" " * wave - ( wx, sy, sz, 1, 1, 1, 1)\n" " * phi - ( 1, 1, 1, 1, 1, tf, tk)\n" " * output - ( sx, sy, sz, 1, md, 1, tk)\n" " * reorder - ( n, 3, 1, 1, 1, 1, 1)\n" " * table - ( wx, nc, n, 1, 1, 1, 1)"; /* Helper function to print out operator dimensions. */ static void print_opdims(const struct linop_s* op) { const struct iovec_s* domain = linop_domain(op); const struct iovec_s* codomain = linop_codomain(op); debug_printf(DP_INFO, "\tDomain: ["); for (long k = 0; k < domain->N; k ++) debug_printf(DP_INFO, "%6ld", domain->dims[k]); debug_printf(DP_INFO, "]\n"); debug_printf(DP_INFO, "\tCodomain: ["); for (long k = 0; k < codomain->N; k ++) debug_printf(DP_INFO, "%6ld", codomain->dims[k]); debug_printf(DP_INFO, "]\n"); } /* Construct sampling mask array from reorder tables. */ static void construct_mask( long reorder_dims[DIMS], complex float* reorder, long mask_dims[DIMS], complex float* mask) { long n = reorder_dims[0]; long sy = mask_dims[1]; long sz = mask_dims[2]; long y = 0; long z = 0; long t = 0; for (int i = 0; i < n; i++) { y = lround(creal(reorder[i])); z = lround(creal(reorder[i + n])); t = lround(creal(reorder[i + 2 * n])); mask[(y + z * sy) + t * sy * sz] = 1; } } struct kern_s { INTERFACE(linop_data_t); unsigned int N; long* reorder_dims; // Dimension of the index table: ( n, 3, 1, 1, 1, 1, 1, 1) long* phi_dims; // Dimension of the temporal basis: ( 1, 1, 1, 1, 1, tf, tk, 1) long* table_dims; // Dimension of the data table: (wx, nc, n, 1, 1, 1, 1, 1) long* kernel_dims; // Dimension of the kernel: ( 1, sy, sz, 1, 1, 1, tk, tk) complex float* reorder; complex float* phi; complex float* kernel; complex float* gpu_kernel; }; static DEF_TYPEID(kern_s); /* Go to table from coefficient-kspace with memory efficiency. */ static void kern_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const struct kern_s* data = CAST_DOWN(kern_s, _data); long wx = data->table_dims[0]; long sy = data->kernel_dims[1]; long sz = data->kernel_dims[2]; long nc = data->table_dims[1]; long n = data->reorder_dims[0]; long tf = data->phi_dims[5]; long tk = data->phi_dims[6]; long input_dims[] = { [0 ... DIMS - 1] = 1 }; input_dims[0] = wx; input_dims[1] = sy; input_dims[2] = sz; input_dims[3] = nc; input_dims[6] = tk; long perm_dims[] = { [0 ... DIMS - 1] = 1 }; perm_dims[0] = wx; perm_dims[1] = nc; perm_dims[3] = tk; perm_dims[4] = sy; perm_dims[5] = sz; complex float* perm = md_alloc_sameplace(DIMS, perm_dims, CFL_SIZE, src); unsigned int permute_order[DIMS] = {0, 3, 5, 6, 1, 2, 4, 7}; for (unsigned int i = 8; i < DIMS; i++) permute_order[i] = i; md_permute(DIMS, permute_order, perm_dims, perm, input_dims, src, CFL_SIZE); long vec_dims[] = {wx, nc, tf, 1}; long phi_mat_dims[] = { 1, 1, tf, tk}; long phi_in_dims[] = {wx, nc, 1, tk}; long fmac_dims[] = {wx, nc, tf, tk}; long line_dims[] = {wx, nc, 1, 1}; complex float* vec = md_alloc_sameplace(4, vec_dims, CFL_SIZE, src); long vec_str[4]; md_calc_strides(4, vec_str, vec_dims, CFL_SIZE); long phi_mat_str[4]; md_calc_strides(4, phi_mat_str, phi_mat_dims, CFL_SIZE); long phi_in_str[4]; md_calc_strides(4, phi_in_str, phi_in_dims, CFL_SIZE); long fmac_str[4]; md_calc_strides(4, fmac_str, fmac_dims, CFL_SIZE); int y = -1; int z = -1; int t = -1; for (int i = 0; i < n; i ++) { y = lround(creal(data->reorder[i])); z = lround(creal(data->reorder[i + n])); t = lround(creal(data->reorder[i + 2 * n])); md_clear(4, vec_dims, vec, CFL_SIZE); md_zfmac2(4, fmac_dims, vec_str, vec, phi_in_str, (perm + ((wx * nc * tk) * (y + z * sy))), phi_mat_str, data->phi); md_copy(4, line_dims, dst + (i * wx * nc), vec + (t * wx * nc), CFL_SIZE); } md_free(perm); md_free(vec); } /* Collapse data table into the temporal basis for memory efficiency. */ static void kern_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { struct kern_s* data = CAST_DOWN(kern_s, _data); long wx = data->table_dims[0]; long sy = data->kernel_dims[1]; long sz = data->kernel_dims[2]; long nc = data->table_dims[1]; long n = data->reorder_dims[0]; long tf = data->phi_dims[5]; long tk = data->phi_dims[6]; long perm_dims[] = { [0 ... DIMS - 1] = 1 }; perm_dims[0] = wx; perm_dims[1] = nc; perm_dims[3] = tk; perm_dims[4] = sy; perm_dims[5] = sz; complex float* perm = md_alloc_sameplace(DIMS, perm_dims, CFL_SIZE, dst); md_clear(DIMS, perm_dims, perm, CFL_SIZE); #ifdef _OPENMP long num_threads = omp_get_max_threads(); #else long num_threads = 1; #endif long vec_dims[] = {wx, nc, tf, 1}; long phi_mat_dims[] = { 1, 1, tf, tk}; long phi_out_dims[] = {wx, nc, 1, tk}; long fmac_dims[] = {wx, nc, tf, tk}; long line_dims[] = {wx, nc, 1, 1}; long vthrd_dims[] = {wx, nc, tf, 1, num_threads}; complex float* vec = md_alloc_sameplace(5, vthrd_dims, CFL_SIZE, dst); md_clear(DIMS, vthrd_dims, vec, CFL_SIZE); long vec_str[4]; md_calc_strides(4, vec_str, vec_dims, CFL_SIZE); long phi_mat_str[4]; md_calc_strides(4, phi_mat_str, phi_mat_dims, CFL_SIZE); long phi_out_str[4]; md_calc_strides(4, phi_out_str, phi_out_dims, CFL_SIZE); long fmac_str[4]; md_calc_strides(4, fmac_str, fmac_dims, CFL_SIZE); long flag_dims[1] = { n }; complex float* flags = md_calloc(1, flag_dims, CFL_SIZE); #pragma omp parallel for for (int k = 0; k < n; k ++) { #ifdef _OPENMP int tid = omp_get_thread_num(); #else int tid = 0; #endif int y = lround(creal(data->reorder[k])); int z = lround(creal(data->reorder[k + n])); int t = -1; if (0 == flags[k]) { md_clear(4, vec_dims, vec + (wx * nc * tf * tid), CFL_SIZE); for (int i = k; i < n; i ++) { if ((y == lround(creal(data->reorder[i]))) && (z == lround(creal(data->reorder[i + n])))) { flags[i] = 1; t = lround(creal(data->reorder[i + 2 * n])); md_copy(4, line_dims, (vec + (wx * nc * tf * tid) + t * wx * nc), (src + i * wx * nc), CFL_SIZE); } } md_zfmacc2(4, fmac_dims, phi_out_str, perm + (y + z * sy) * (wx * nc * tk), vec_str, vec + (wx * nc * tf * tid), phi_mat_str, data->phi); } } long out_dims[] = { [0 ... DIMS - 1] = 1 }; out_dims[0] = wx; out_dims[1] = sy; out_dims[2] = sz; out_dims[3] = nc; out_dims[6] = tk; unsigned int permute_order[DIMS] = {0, 4, 5, 1, 6, 2, 3, 7}; for (unsigned int i = 8; i < DIMS; i++) permute_order[i] = i; md_permute(DIMS, permute_order, out_dims, dst, perm_dims, perm, CFL_SIZE); md_free(vec); md_free(perm); md_free(flags); } static void kern_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { const struct kern_s* data = CAST_DOWN(kern_s, _data); long wx = data->table_dims[0]; long sy = data->kernel_dims[1]; long sz = data->kernel_dims[2]; long nc = data->table_dims[1]; long tk = data->phi_dims[6]; long input_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; input_dims[0] = wx; input_dims[1] = sy; input_dims[2] = sz; input_dims[3] = nc; input_dims[6] = tk; long input_str[DIMS]; md_calc_strides(DIMS, input_str, input_dims, CFL_SIZE); long output_dims[DIMS]; md_copy_dims(DIMS, output_dims, input_dims); output_dims[6] = 1; output_dims[7] = tk; long output_str[DIMS]; md_calc_strides(DIMS, output_str, output_dims, CFL_SIZE); long gpu_kernel_dims[DIMS] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, gpu_kernel_dims, data->kernel_dims); gpu_kernel_dims[0] = wx; gpu_kernel_dims[3] = nc; long kernel_str[DIMS]; md_calc_strides(DIMS, kernel_str, data->kernel_dims, CFL_SIZE); long gpu_kernel_str[DIMS]; md_calc_strides(DIMS, gpu_kernel_str, gpu_kernel_dims, CFL_SIZE); long fmac_dims[DIMS]; md_merge_dims(DIMS, fmac_dims, input_dims, data->kernel_dims); md_clear(DIMS, output_dims, dst, CFL_SIZE); #ifdef USE_CUDA if(cuda_ondevice(src)) md_zfmac2(DIMS, fmac_dims, output_str, dst, input_str, src, gpu_kernel_str, data->gpu_kernel); else #endif md_zfmac2(DIMS, fmac_dims, output_str, dst, input_str, src, kernel_str, data->kernel); } static void kern_free(const linop_data_t* _data) { const struct kern_s* data = CAST_DOWN(kern_s, _data); xfree(data->reorder_dims); xfree(data->phi_dims); xfree(data->table_dims); xfree(data->kernel_dims); #ifdef USE_CUDA if (data->gpu_kernel != NULL) md_free(data->gpu_kernel); #endif xfree(data); } static const struct linop_s* linop_kern_create(bool gpu_flag, const long _reorder_dims[DIMS], complex float* reorder, const long _phi_dims[DIMS], complex float* phi, const long _kernel_dims[DIMS], complex float* kernel, const long _table_dims[DIMS]) { PTR_ALLOC(struct kern_s, data); SET_TYPEID(kern_s, data); PTR_ALLOC(long[DIMS], reorder_dims); PTR_ALLOC(long[DIMS], phi_dims); PTR_ALLOC(long[DIMS], table_dims); PTR_ALLOC(long[DIMS], kernel_dims); md_copy_dims(DIMS, *reorder_dims, _reorder_dims); md_copy_dims(DIMS, *phi_dims, _phi_dims); md_copy_dims(DIMS, *table_dims, _table_dims); md_copy_dims(DIMS, *kernel_dims, _kernel_dims); data->reorder_dims = *PTR_PASS(reorder_dims); data->phi_dims = *PTR_PASS(phi_dims); data->table_dims = *PTR_PASS(table_dims); data->kernel_dims = *PTR_PASS(kernel_dims); data->reorder = reorder; data->phi = phi; data->kernel = kernel; data->gpu_kernel = NULL; #ifdef USE_CUDA if(gpu_flag) { long repmat_kernel_dims[DIMS] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, repmat_kernel_dims, _kernel_dims); repmat_kernel_dims[0] = _table_dims[0]; repmat_kernel_dims[3] = _table_dims[1]; long kernel_strs[DIMS]; long repmat_kernel_strs[DIMS]; md_calc_strides(DIMS, kernel_strs, _kernel_dims, CFL_SIZE); md_calc_strides(DIMS, repmat_kernel_strs, repmat_kernel_dims, CFL_SIZE); complex float* repmat_kernel = md_calloc(DIMS, repmat_kernel_dims, CFL_SIZE); md_copy2(DIMS, repmat_kernel_dims, repmat_kernel_strs, repmat_kernel, kernel_strs, kernel, CFL_SIZE); data->gpu_kernel = md_gpu_move(DIMS, repmat_kernel_dims, repmat_kernel, CFL_SIZE); md_free(repmat_kernel); } #else UNUSED(gpu_flag); #endif long input_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; input_dims[0] = _table_dims[0]; input_dims[1] = _kernel_dims[1]; input_dims[2] = _kernel_dims[2]; input_dims[3] = _table_dims[1]; input_dims[6] = _phi_dims[6]; long output_dims[DIMS] = { [0 ... DIMS - 1] = 1 }; output_dims[0] = _table_dims[0]; output_dims[1] = _table_dims[1]; output_dims[2] = _reorder_dims[0]; const struct linop_s* K = linop_create(DIMS, output_dims, DIMS, input_dims, CAST_UP(PTR_PASS(data)), kern_apply, kern_adjoint, kern_normal, NULL, kern_free); return K; } struct multc_s { INTERFACE(linop_data_t); unsigned int nc; unsigned int md; const complex float* maps; const struct linop_s* sc_op; // Single channel operator. }; static DEF_TYPEID(multc_s); static void multc_apply(const linop_data_t* _data, complex float* dst, const complex float* src) { const struct multc_s* data = CAST_DOWN(multc_s, _data); // Loading single channel operator. const struct operator_s* fwd = data->sc_op->forward; const long* sc_inp_dims = linop_domain(data->sc_op)->dims; const long* sc_out_dims = linop_codomain(data->sc_op)->dims; long sx = sc_inp_dims[0]; long sy = sc_inp_dims[1]; long sz = sc_inp_dims[2]; long wx = sc_out_dims[0]; long n = sc_out_dims[2]; long nc = data->nc; long md = data->md; long src_dims[] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, src_dims, sc_inp_dims); src_dims[MAPS_DIM] = md; long dst_dims[] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, dst_dims, sc_out_dims); dst_dims[1] = nc; long map_dims[] = { [0 ... DIMS - 1] = 1}; map_dims[0] = sx; map_dims[1] = sy; map_dims[2] = sz; map_dims[3] = nc; map_dims[4] = md; long single_map_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, single_map_dims, map_dims); single_map_dims[COIL_DIM] = 1; complex float* single_map = md_alloc_sameplace(DIMS, single_map_dims, CFL_SIZE, src); complex float* buffer = md_alloc_sameplace(DIMS, sc_inp_dims, CFL_SIZE, src); long tbl_dims[] = { [0 ... DIMS - 1] = 1}; tbl_dims[0] = wx; tbl_dims[1] = n; tbl_dims[2] = nc; complex float* tbl = md_alloc_sameplace(DIMS, tbl_dims, CFL_SIZE, src); md_clear(DIMS, tbl_dims, tbl, CFL_SIZE); long pos[] = { [0 ... DIMS - 1] = 0 }; long zfmac_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, zfmac_dims, src_dims); long strides_single_map[DIMS]; md_calc_strides(DIMS, strides_single_map, single_map_dims, CFL_SIZE); long strides_src[DIMS]; md_calc_strides(DIMS, strides_src, src_dims, CFL_SIZE); long strides_sc_inp[DIMS]; md_calc_strides(DIMS, strides_sc_inp, sc_inp_dims, CFL_SIZE); for (long k = 0; k < data->nc; k++) { md_clear(DIMS, single_map_dims, single_map, CFL_SIZE); md_clear(DIMS, sc_inp_dims, buffer, CFL_SIZE); pos[COIL_DIM] = k; md_slice(DIMS, COIL_FLAG, pos, map_dims, single_map, data->maps, CFL_SIZE); pos[COIL_DIM] = 0; md_zfmac2(DIMS, zfmac_dims, strides_sc_inp, buffer, strides_src, src, strides_single_map, single_map); operator_apply(fwd, DIMS, sc_out_dims, tbl + (wx * n * k), DIMS, sc_inp_dims, buffer); } md_clear(DIMS, dst_dims, dst, CFL_SIZE); unsigned int permute_order[DIMS] = {0, 2, 1}; for (unsigned int i = 3; i < DIMS; i++) permute_order[i] = i; md_permute(DIMS, permute_order, dst_dims, dst, tbl_dims, tbl, CFL_SIZE); md_free(single_map); md_free(buffer); md_free(tbl); } static void multc_adjoint(const linop_data_t* _data, complex float* dst, const complex float* src) { const struct multc_s* data = CAST_DOWN(multc_s, _data); // Loading single channel operator. const struct operator_s* adj = data->sc_op->adjoint; const long* sc_inp_dims = linop_codomain(data->sc_op)->dims; const long* sc_out_dims = linop_domain(data->sc_op)->dims; long sx = sc_out_dims[0]; long sy = sc_out_dims[1]; long sz = sc_out_dims[2]; long wx = sc_inp_dims[0]; long n = sc_inp_dims[2]; long nc = data->nc; long md = data->md; long src_dims[] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, src_dims, sc_inp_dims); src_dims[1] = nc; long dst_dims[] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, dst_dims, sc_out_dims); dst_dims[MAPS_DIM] = md; long map_dims[] = { [0 ... DIMS - 1] = 1}; map_dims[0] = sx; map_dims[1] = sy; map_dims[2] = sz; map_dims[3] = nc; map_dims[4] = md; long single_map_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, single_map_dims, map_dims); single_map_dims[COIL_DIM] = 1; complex float* single_map = md_alloc_sameplace(DIMS, single_map_dims, CFL_SIZE, src); complex float* buffer1 = md_alloc_sameplace(DIMS, sc_out_dims, CFL_SIZE, src); complex float* buffer2 = md_alloc_sameplace(DIMS, dst_dims, CFL_SIZE, src); long tbl_dims[] = { [0 ... DIMS - 1] = 1}; tbl_dims[0] = wx; tbl_dims[2] = n; complex float* tbl = md_alloc_sameplace(DIMS, tbl_dims, CFL_SIZE, src); long pos[] = { [0 ... DIMS - 1] = 0 }; long strides_single_map[DIMS]; md_calc_strides(DIMS, strides_single_map, single_map_dims, CFL_SIZE); long strides_sc_out[DIMS]; md_calc_strides(DIMS, strides_sc_out, sc_out_dims, CFL_SIZE); long strides_dst[DIMS]; md_calc_strides(DIMS, strides_dst, dst_dims, CFL_SIZE); md_clear(DIMS, dst_dims, dst, CFL_SIZE); for (long k = 0; k < data->nc; k++) { md_clear(DIMS, single_map_dims, single_map, CFL_SIZE); md_clear(DIMS, sc_out_dims, buffer1, CFL_SIZE); md_clear(DIMS, dst_dims, buffer2, CFL_SIZE); md_clear(DIMS, tbl_dims, tbl, CFL_SIZE); pos[1] = k; md_slice(DIMS, 2, pos, src_dims, tbl, src, CFL_SIZE); pos[1] = 0; operator_apply(adj, DIMS, sc_out_dims, buffer1, DIMS, tbl_dims, tbl); pos[COIL_DIM] = k; md_slice(DIMS, COIL_FLAG, pos, map_dims, single_map, data->maps, CFL_SIZE); pos[COIL_DIM] = 0; md_zfmacc2(DIMS, dst_dims, strides_dst, buffer2, strides_sc_out, buffer1, strides_single_map, single_map); md_zadd(DIMS, dst_dims, dst, dst, buffer2); } md_free(single_map); md_free(buffer1); md_free(buffer2); md_free(tbl); } static void multc_normal(const linop_data_t* _data, complex float* dst, const complex float* src) { const struct multc_s* data = CAST_DOWN(multc_s, _data); // Loading single channel operator. const struct operator_s* nrm = data->sc_op->normal; const long* sc_dims = linop_domain(data->sc_op)->dims; long sx = sc_dims[0]; long sy = sc_dims[1]; long sz = sc_dims[2]; long nc = data->nc; long md = data->md; long dims[] = { [0 ... DIMS - 1] = 1}; md_copy_dims(DIMS, dims, sc_dims); dims[MAPS_DIM] = md; long map_dims[] = { [0 ... DIMS - 1] = 1}; map_dims[0] = sx; map_dims[1] = sy; map_dims[2] = sz; map_dims[3] = nc; map_dims[4] = md; long single_map_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, single_map_dims, map_dims); single_map_dims[COIL_DIM] = 1; complex float* single_map = md_alloc_sameplace(DIMS, single_map_dims, CFL_SIZE, src); complex float* buffer1 = md_alloc_sameplace(DIMS, sc_dims, CFL_SIZE, src); complex float* buffer2 = md_alloc_sameplace(DIMS, sc_dims, CFL_SIZE, src); complex float* buffer3 = md_alloc_sameplace(DIMS, dims, CFL_SIZE, src); long pos[] = { [0 ... DIMS - 1] = 0 }; long strides_single_map[DIMS]; md_calc_strides(DIMS, strides_single_map, single_map_dims, CFL_SIZE); long strides_sc[DIMS]; md_calc_strides(DIMS, strides_sc, sc_dims, CFL_SIZE); long strides[DIMS]; md_calc_strides(DIMS, strides, dims, CFL_SIZE); md_clear(DIMS, dims, dst, CFL_SIZE); for (long k = 0; k < data->nc; k++) { md_clear(DIMS, single_map_dims, single_map, CFL_SIZE); md_clear(DIMS, sc_dims, buffer1, CFL_SIZE); md_clear(DIMS, sc_dims, buffer2, CFL_SIZE); md_clear(DIMS, dims, buffer3, CFL_SIZE); pos[COIL_DIM] = k; md_slice(DIMS, COIL_FLAG, pos, map_dims, single_map, data->maps, CFL_SIZE); pos[COIL_DIM] = 0; md_zfmac2(DIMS, dims, strides_sc, buffer1, strides, src, strides_single_map, single_map); operator_apply(nrm, DIMS, sc_dims, buffer2, DIMS, sc_dims, buffer1); md_zfmacc2(DIMS, dims, strides, buffer3, strides_sc, buffer2, strides_single_map, single_map); md_zadd(DIMS, dims, dst, dst, buffer3); } md_free(single_map); md_free(buffer1); md_free(buffer2); md_free(buffer3); } static void multc_free(const linop_data_t* _data) { const struct multc_s* data = CAST_DOWN(multc_s, _data); xfree(data); } static struct linop_s* linop_multc_create(long nc, long md, const complex float* maps, const struct linop_s* sc_op) { PTR_ALLOC(struct multc_s, data); SET_TYPEID(multc_s, data); data->nc = nc; data->md = md; data->maps = maps; data->sc_op = sc_op; long* op_inp_dims = (long*) linop_domain(sc_op)->dims; long* op_out_dims = (long*) linop_codomain(sc_op)->dims; long input_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, input_dims, op_inp_dims); input_dims[MAPS_DIM] = md; long output_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, output_dims, op_out_dims); output_dims[1] = nc; struct linop_s* E = linop_create(DIMS, output_dims, DIMS, input_dims, CAST_UP(PTR_PASS(data)), multc_apply, multc_adjoint, multc_normal, NULL, multc_free); return E; } /* Resize operator. */ static const struct linop_s* linop_wavereshape_create(long wx, long sx, long sy, long sz, long nc, long tk) { long input_dims[] = { [0 ... DIMS - 1] = 1}; input_dims[0] = sx; input_dims[1] = sy; input_dims[2] = sz; input_dims[3] = nc; input_dims[6] = tk; long output_dims[DIMS]; md_copy_dims(DIMS, output_dims, input_dims); output_dims[0] = wx; struct linop_s* R = linop_resize_create(DIMS, output_dims, input_dims); return R; } /* Fx operator. */ static const struct linop_s* linop_fx_create(long wx, long sy, long sz, long nc, long tk, bool centered) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; dims[6] = tk; struct linop_s* Fx = NULL; if (centered) Fx = linop_fftc_create(DIMS, dims, READ_FLAG); else Fx = linop_fft_create(DIMS, dims, READ_FLAG); return Fx; } /* Wave operator. */ static const struct linop_s* linop_wave_create(long wx, long sy, long sz, long nc, long tk, long psf_tk, complex float* psf) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; dims[6] = tk; return (psf_tk > 1) ? linop_cdiag_create(DIMS, dims, FFT_FLAGS | COEFF_FLAG, psf) : linop_cdiag_create(DIMS, dims, FFT_FLAGS, psf); } /* Fyz operator. */ static const struct linop_s* linop_fyz_create(long wx, long sy, long sz, long nc, long tk, bool centered) { long dims[] = { [0 ... DIMS - 1] = 1}; dims[0] = wx; dims[1] = sy; dims[2] = sz; dims[3] = nc; dims[6] = tk; struct linop_s* Fyz = NULL; if (centered) Fyz = linop_fftc_create(DIMS, dims, PHS1_FLAG|PHS2_FLAG); else Fyz = linop_fft_create(DIMS, dims, PHS1_FLAG|PHS2_FLAG); return Fyz; } /* Construction sampling temporal kernel.*/ static void construct_kernel( long mask_dims[DIMS], complex float* mask, long phi_dims[DIMS], complex float* phi, long kern_dims[DIMS], complex float* kern) { long sy = mask_dims[1]; long sz = mask_dims[2]; long tf = phi_dims[5]; long tk = phi_dims[6]; long cvec_dims[] = { [0 ... DIMS - 1] = 1 }; cvec_dims[6] = tk; long cvec_str[DIMS]; md_calc_strides(DIMS, cvec_str, cvec_dims, CFL_SIZE); complex float cvec[tk]; long tvec_dims[] = { [0 ... DIMS - 1] = 1 }; tvec_dims[5] = tf; long tvec_str[DIMS]; md_calc_strides(DIMS, tvec_str, tvec_dims, CFL_SIZE); complex float mvec[tf]; complex float tvec1[tf]; complex float tvec2[tf]; long phi_str[DIMS]; md_calc_strides(DIMS, phi_str, phi_dims, CFL_SIZE); long out_dims[] = { [0 ... DIMS - 1] = 1 }; out_dims[0] = tk; out_dims[1] = sy; out_dims[2] = sz; out_dims[3] = tk; complex float* out = md_calloc(DIMS, out_dims, CFL_SIZE); for (int y = 0; y < sy; y ++) { for (int z = 0; z < sz; z ++) { for (int t = 0; t < tf; t ++) mvec[t] = mask[(y + sy * z) + (sy * sz) * t]; for (int t = 0; t < tk; t ++) { cvec[t] = 1; md_clear(DIMS, tvec_dims, tvec1, CFL_SIZE); md_zfmac2(DIMS, phi_dims, tvec_str, tvec1, cvec_str, cvec, phi_str, phi); md_clear(DIMS, tvec_dims, tvec2, CFL_SIZE); md_zfmac2(DIMS, tvec_dims, tvec_str, tvec2, tvec_str, tvec1, tvec_str, mvec); md_clear(DIMS, cvec_dims, out + y * tk + z * sy * tk + t * sy * sz * tk, CFL_SIZE); md_zfmacc2(DIMS, phi_dims, cvec_str, out + y * tk + z * sy * tk + t * sy * sz * tk, tvec_str, tvec2, phi_str, phi); cvec[t] = 0; } } } unsigned int permute_order[DIMS] = {4, 1, 2, 5, 6, 7, 3, 0}; for (unsigned int i = 8; i < DIMS; i++) permute_order[i] = i; md_permute(DIMS, permute_order, kern_dims, kern, out_dims, out, CFL_SIZE); md_free(out); } static void fftmod_apply(long sy, long sz, long reorder_dims[DIMS], complex float* reorder, long table_dims[DIMS], complex float* table, long maps_dims[DIMS], complex float* maps) { long wx = table_dims[0]; long nc = table_dims[1]; fftmod(DIMS, table_dims, READ_FLAG, table, table); fftmod(DIMS, maps_dims, FFT_FLAGS, maps, maps); long y = -1; long z = -1; double dy = ((double) sy/2)/((double) sy); double dz = ((double) sz/2)/((double) sz); complex float py = 1; complex float pz = 1; long dims[] = { [0 ... DIMS] = 1}; dims[0] = wx; dims[1] = nc; long n = reorder_dims[0]; for (long k = 0; k < n; k++) { y = lround(creal(reorder[k])); z = lround(creal(reorder[k + n])); py = cexp(2.i * M_PI * dy * y); pz = cexp(2.i * M_PI * dz * z); md_zsmul(DIMS, dims, table + k * wx * nc, table + k * wx * nc, py * pz); } } enum algo_t { CG, IST, FISTA }; int main_wshfl(int argc, char* argv[]) { double start_time = timestamp(); float lambda = 1E-5; int maxiter = 300; int blksize = 8; float step = 0.5; float tol = 1.E-3; bool llr = false; bool wav = false; bool fista = false; bool hgwld = false; float cont = 1; float eval = -1; const char* fwd = NULL; const char* x0 = NULL; int gpun = -1; bool dcx = false; bool pf = false; const struct opt_s opts[] = { OPT_FLOAT( 'r', &lambda, "lambda", "Soft threshold lambda for wavelet or locally low rank."), OPT_INT( 'b', &blksize, "blkdim", "Block size for locally low rank."), OPT_INT( 'i', &maxiter, "mxiter", "Maximum number of iterations."), OPT_FLOAT( 's', &step, "stepsz", "Step size for iterative method."), OPT_FLOAT( 'c', &cont, "cntnu", "Continuation value for IST/FISTA."), OPT_FLOAT( 't', &tol, "toler", "Tolerance convergence condition for iterative method."), OPT_FLOAT( 'e', &eval, "eigvl", "Maximum eigenvalue of normal operator, if known."), OPT_STRING('F', &fwd, "frwrd", "Go from shfl-coeffs to data-table. Pass in coeffs path."), OPT_STRING('O', &x0, "initl", "Initialize reconstruction with guess."), OPT_INT( 'g', &gpun, "gpunm", "GPU device number."), OPT_SET( 'f', &fista, "Reconstruct using FISTA instead of IST."), OPT_SET( 'H', &hgwld, "Use hogwild in IST/FISTA."), OPT_SET( 'v', &dcx, "Split coefficients to real and imaginary components."), OPT_SET( 'w', &wav, "Use wavelet."), OPT_SET( 'l', &llr, "Use locally low rank across temporal coefficients."), OPT_SET( 'p', &pf, "Use locally low rank and real-imaginary components for partial fourier."), }; cmdline(&argc, argv, 6, 6, usage_str, help_str, ARRAY_SIZE(opts), opts); if (pf) dcx = true; debug_printf(DP_INFO, "Loading data... "); long maps_dims[DIMS]; complex float* maps = load_cfl(argv[1], DIMS, maps_dims); long wave_dims[DIMS]; complex float* wave = load_cfl(argv[2], DIMS, wave_dims); long phi_dims[DIMS]; complex float* phi = load_cfl(argv[3], DIMS, phi_dims); long reorder_dims[DIMS]; complex float* reorder = load_cfl(argv[4], DIMS, reorder_dims); long table_dims[DIMS]; complex float* table = load_cfl(argv[5], DIMS, table_dims); debug_printf(DP_INFO, "Done.\n"); if (gpun >= 0) num_init_gpu_device(gpun); else num_init(); int wx = wave_dims[0]; int sx = maps_dims[0]; int sy = maps_dims[1]; int sz = maps_dims[2]; int nc = maps_dims[3]; int md = maps_dims[4]; int tf = phi_dims[5]; int tk = phi_dims[6]; debug_printf(DP_INFO, "Constructing sampling mask from reorder table... "); long mask_dims[] = { [0 ... DIMS - 1] = 1 }; mask_dims[1] = sy; mask_dims[2] = sz; mask_dims[5] = tf; complex float* mask = md_calloc(DIMS, mask_dims, CFL_SIZE); construct_mask(reorder_dims, reorder, mask_dims, mask); debug_printf(DP_INFO, "Done.\n"); debug_printf(DP_INFO, "Constructing sampling-temporal kernel... "); long kernel_dims[] = { [0 ... DIMS - 1] = 1 }; kernel_dims[1] = sy; kernel_dims[2] = sz; kernel_dims[6] = tk; kernel_dims[7] = tk; complex float* kernel = md_calloc(DIMS, kernel_dims, CFL_SIZE); construct_kernel(mask_dims, mask, phi_dims, phi, kernel_dims, kernel); md_free(mask); debug_printf(DP_INFO, "Done.\n"); long coeff_dims[] = { [0 ... DIMS - 1] = 1 }; coeff_dims[0] = sx; coeff_dims[1] = sy; coeff_dims[2] = sz; coeff_dims[4] = md; coeff_dims[6] = tk; coeff_dims[8] = dcx ? 2 : 1; debug_printf(DP_INFO, "Creating single channel linear operators:\n"); double t1; double t2; t1 = timestamp(); const struct linop_s* R = linop_wavereshape_create(wx, sx, sy, sz, 1, tk); t2 = timestamp(); debug_printf(DP_INFO, "\tR: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* Fx = linop_fx_create(wx, sy, sz, 1, tk, false); t2 = timestamp(); debug_printf(DP_INFO, "\tFx: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* W = linop_wave_create(wx, sy, sz, 1, tk, wave_dims[COEFF_DIM], wave); t2 = timestamp(); debug_printf(DP_INFO, "\tW: %f seconds.\n", t2 - t1); t1 = timestamp(); const struct linop_s* Fyz = linop_fyz_create(wx, sy, sz, 1, tk, false); t2 = timestamp(); debug_printf(DP_INFO, "\tFyz: %f seconds.\n", t2 - t1); t1 = timestamp(); long single_channel_table_dims[] = { [0 ... DIMS - 1] = 1 }; md_copy_dims(DIMS, single_channel_table_dims, table_dims); single_channel_table_dims[1] = 1; const struct linop_s* K = linop_kern_create(gpun >= 0, reorder_dims, reorder, phi_dims, phi, kernel_dims, kernel, single_channel_table_dims); t2 = timestamp(); debug_printf(DP_INFO, "\tK: %f seconds.\n", t2 - t1); struct linop_s* A_sc = linop_chain_FF(linop_chain_FF(linop_chain_FF(linop_chain_FF( R, Fx), W), Fyz), K); debug_printf(DP_INFO, "Single channel forward operator information:\n"); print_opdims(A_sc); if (eval < 0) #ifdef USE_CUDA eval = (gpun >= 0) ? estimate_maxeigenval_gpu(A_sc->normal) : estimate_maxeigenval(A_sc->normal); #else eval = estimate_maxeigenval(A_sc->normal); #endif debug_printf(DP_INFO, "\tMax eval: %.2e\n", eval); step /= eval; struct linop_s* A = linop_multc_create(nc, md, maps, A_sc); debug_printf(DP_INFO, "Overall forward linear operator information:\n"); print_opdims(A); if (fwd != NULL) { debug_printf(DP_INFO, "Going from coefficients to data table... "); complex float* coeffs_to_fwd = load_cfl(fwd, DIMS, coeff_dims); complex float* table_forward = create_cfl(argv[6], DIMS, table_dims); const struct linop_s* R = linop_wavereshape_create(wx, sx, sy, sz, 1, tk); const struct linop_s* CFx = linop_fx_create( wx, sy, sz, 1, tk, true); const struct linop_s* W = linop_wave_create(wx, sy, sz, 1, tk, wave_dims[COEFF_DIM], wave); const struct linop_s* CFyz = linop_fyz_create(wx, sy, sz, 1, tk, true); const struct linop_s* K = linop_kern_create(gpun >= 0, reorder_dims, reorder, phi_dims, phi, kernel_dims, kernel, single_channel_table_dims); struct linop_s* AC_sc = linop_chain_FF(linop_chain_FF(linop_chain_FF(linop_chain_FF( R, CFx), W), CFyz), K); struct linop_s* AC = linop_multc_create(nc, md, maps, AC_sc); operator_apply(AC->forward, DIMS, table_dims, table_forward, DIMS, coeff_dims, coeffs_to_fwd); debug_printf(DP_INFO, "Done.\n"); debug_printf(DP_INFO, "Cleaning up... "); linop_free(AC); linop_free(AC_sc); md_free(kernel); unmap_cfl(DIMS, maps_dims, maps); unmap_cfl(DIMS, wave_dims, wave); unmap_cfl(DIMS, phi_dims, phi); unmap_cfl(DIMS, reorder_dims, reorder); unmap_cfl(DIMS, table_dims, table); unmap_cfl(DIMS, table_dims, table_forward); debug_printf(DP_INFO, "Done.\n"); return 0; } if (dcx) { debug_printf(DP_INFO, "\tSplitting result into real and imaginary components.\n"); struct linop_s* tmp = A; struct linop_s* dcxop = linop_decompose_complex_create(DIMS, ITER_DIM, linop_domain(A)->dims); A = linop_chain(dcxop, tmp); linop_free(dcxop); linop_free(tmp); } debug_printf(DP_INFO, "Normalizing data table and applying fftmod to table and maps... "); float norm = md_znorm(DIMS, table_dims, table); md_zsmul(DIMS, table_dims, table, table, 1. / norm); fftmod_apply(sy, sz, reorder_dims, reorder, table_dims, table, maps_dims, maps); debug_printf(DP_INFO, "Done.\n"); const struct operator_p_s* T = NULL; long blkdims[MAX_LEV][DIMS]; long minsize[] = { [0 ... DIMS - 1] = 1 }; minsize[0] = MIN(sx, 16); minsize[1] = MIN(sy, 16); minsize[2] = MIN(sz, 16); unsigned int WAVFLAG = (sx > 1) * READ_FLAG | (sy > 1) * PHS1_FLAG | (sz > 2) * PHS2_FLAG; enum algo_t algo = CG; if ((wav) || (llr) || (pf)) { algo = (fista) ? FISTA : IST; if (wav) { debug_printf(DP_INFO, "Creating wavelet threshold operator... "); T = prox_wavelet_thresh_create(DIMS, coeff_dims, WAVFLAG, 0u, minsize, lambda, true); } else if (llr) { debug_printf(DP_INFO, "Creating locally low rank threshold operator across coeff and real-imag... "); llr_blkdims(blkdims, ~(COEFF_FLAG | ITER_FLAG), coeff_dims, blksize); T = lrthresh_create(coeff_dims, true, ~(COEFF_FLAG | ITER_FLAG), (const long (*)[])blkdims, lambda, false, false, false); } else { assert(dcx); debug_printf(DP_INFO, "Creating locally low rank threshold operator across real-imag... "); llr_blkdims(blkdims, ~ITER_FLAG, coeff_dims, blksize); T = lrthresh_create(coeff_dims, true, ~ITER_FLAG, (const long (*)[])blkdims, lambda, false, false, false); } debug_printf(DP_INFO, "Done.\n"); } italgo_fun2_t italgo = iter2_call_iter; struct iter_call_s iter2_data; SET_TYPEID(iter_call_s, &iter2_data); iter_conf* iconf = CAST_UP(&iter2_data); struct iter_conjgrad_conf cgconf = iter_conjgrad_defaults; struct iter_fista_conf fsconf = iter_fista_defaults; struct iter_ist_conf isconf = iter_ist_defaults; switch(algo) { case IST: debug_printf(DP_INFO, "Using IST.\n"); debug_printf(DP_INFO, "\tLambda: %0.2e\n", lambda); debug_printf(DP_INFO, "\tMaximum iterations: %d\n", maxiter); debug_printf(DP_INFO, "\tStep size: %0.2e\n", step); debug_printf(DP_INFO, "\tHogwild: %d\n", (int) hgwld); debug_printf(DP_INFO, "\tTolerance: %0.2e\n", tol); debug_printf(DP_INFO, "\tContinuation: %0.2e\n", cont); isconf = iter_ist_defaults; isconf.step = step; isconf.maxiter = maxiter; isconf.tol = tol; isconf.continuation = cont; isconf.hogwild = hgwld; iter2_data.fun = iter_ist; iter2_data._conf = CAST_UP(&isconf); break; case FISTA: debug_printf(DP_INFO, "Using FISTA.\n"); debug_printf(DP_INFO, "\tLambda: %0.2e\n", lambda); debug_printf(DP_INFO, "\tMaximum iterations: %d\n", maxiter); debug_printf(DP_INFO, "\tStep size: %0.2e\n", step); debug_printf(DP_INFO, "\tHogwild: %d\n", (int) hgwld); debug_printf(DP_INFO, "\tTolerance: %0.2e\n", tol); debug_printf(DP_INFO, "\tContinuation: %0.2e\n", cont); fsconf = iter_fista_defaults; fsconf.maxiter = maxiter; fsconf.step = step; fsconf.hogwild = hgwld; fsconf.tol = tol; fsconf.continuation = cont; iter2_data.fun = iter_fista; iter2_data._conf = CAST_UP(&fsconf); break; default: case CG: debug_printf(DP_INFO, "Using CG.\n"); debug_printf(DP_INFO, "\tMaximum iterations: %d\n", maxiter); debug_printf(DP_INFO, "\tTolerance: %0.2e\n", tol); cgconf = iter_conjgrad_defaults; cgconf.maxiter = maxiter; cgconf.l2lambda = 0; cgconf.tol = tol; iter2_data.fun = iter_conjgrad; iter2_data._conf = CAST_UP(&cgconf); break; } complex float* init = NULL; if (x0 != NULL) { debug_printf(DP_INFO, "Loading in initial guess... "); init = load_cfl(x0, DIMS, coeff_dims); debug_printf(DP_INFO, "Done.\n"); } debug_printf(DP_INFO, "Reconstruction... "); complex float* recon = create_cfl(argv[6], DIMS, coeff_dims); struct lsqr_conf lsqr_conf = { 0., gpun >= 0 }; double recon_start = timestamp(); const struct operator_p_s* J = lsqr2_create(&lsqr_conf, italgo, iconf, (const float*) init, A, NULL, 1, &T, NULL, NULL); operator_p_apply(J, 1., DIMS, coeff_dims, recon, DIMS, table_dims, table); double recon_end = timestamp(); debug_printf(DP_INFO, "Done.\nReconstruction time: %f seconds.\n", recon_end - recon_start); debug_printf(DP_INFO, "Cleaning up and saving result... "); operator_p_free(J); linop_free(A); linop_free(A_sc); md_free(kernel); unmap_cfl(DIMS, maps_dims, maps); unmap_cfl(DIMS, wave_dims, wave); unmap_cfl(DIMS, phi_dims, phi); unmap_cfl(DIMS, reorder_dims, reorder); unmap_cfl(DIMS, table_dims, table); unmap_cfl(DIMS, coeff_dims, recon); if (x0 != NULL) unmap_cfl(DIMS, coeff_dims, init); debug_printf(DP_INFO, "Done.\n"); double end_time = timestamp(); debug_printf(DP_INFO, "Total time: %f seconds.\n", end_time - start_time); return 0; } bart-0.5.00/src/zeros.c000066400000000000000000000020721353046746100146330ustar00rootroot00000000000000/* Copyright 2013. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2012-06-04 Martin Uecker */ #include #include #include #include #include #include "num/multind.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/io.h" #include "misc/misc.h" static const char usage_str[] = "dims dim1 ... dimn name"; static const char help_str[] = "Create a zero-filled array with {dims} dimensions of size {dim1} to {dimn}.\n"; int main_zeros(int argc, char* argv[]) { mini_cmdline(&argc, argv, -3, usage_str, help_str); num_init(); int N = atoi(argv[1]); assert(N >= 0); assert(argc == 3 + N); long dims[N]; for (int i = 0; i < N; i++) { dims[i] = atoi(argv[2 + i]); assert(dims[i] >= 1); } complex float* x = create_cfl(argv[2 + N], N, dims); md_clear(N, dims, x, sizeof(complex float)); unmap_cfl(N, dims, x); return 0; } bart-0.5.00/src/zexp.c000066400000000000000000000023351353046746100144610ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jon Tamir * 2018 Martin Uecker */ #include #include #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/init.h" #include "misc/mmio.h" #include "misc/misc.h" #include "misc/opts.h" #ifndef DIMS #define DIMS 16 #endif static const char usage_str[] = " "; static const char help_str[] = "Point-wise complex exponential.\n"; int main_zexp(int argc, char* argv[argc]) { bool img = false; const struct opt_s opts[] = { OPT_SET('i', &img, "imaginary"), }; cmdline(&argc, argv, 2, 2, usage_str, help_str, ARRAY_SIZE(opts), opts); num_init(); long dims[DIMS]; complex float* in_data = load_cfl(argv[1], DIMS, dims); complex float* out_data = create_cfl(argv[2], DIMS, dims); (img ? md_zexpj : md_zexp)(DIMS, dims, out_data, in_data); unmap_cfl(DIMS, dims, in_data); unmap_cfl(DIMS, dims, out_data); return 0; } bart-0.5.00/startup.m000066400000000000000000000001701353046746100144130ustar00rootroot00000000000000% set Matlab path and TOOLBOX_PATH environment variable addpath(fullfile(pwd, 'matlab')); setenv('TOOLBOX_PATH', pwd); bart-0.5.00/startup.py000066400000000000000000000001771353046746100146160ustar00rootroot00000000000000import os import sys path = os.environ["TOOLBOX_PATH"] + "/python/"; sys.path.append(path); from bart import bart import cfl bart-0.5.00/startup.sh000066400000000000000000000001671353046746100145770ustar00rootroot00000000000000# set environment variables #export OMP_NUM_THREADS=23 export TOOLBOX_PATH=`pwd` export PATH=${TOOLBOX_PATH}:${PATH} bart-0.5.00/sub000077500000000000000000000003751353046746100132610ustar00rootroot00000000000000#!/bin/bash set -e if [ ! -f ${TOOLBOX_PATH}/$(basename $0) ] ; then echo "\$TOOLBOX_PATH is not set correctly!" exit 1 fi if [ $# -lt 3 ] ; then echo "Usage: $0 " exit 1 fi ${TOOLBOX_PATH}/bart saxpy -- -1. $1 $2 $3 bart-0.5.00/tests/000077500000000000000000000000001353046746100136775ustar00rootroot00000000000000bart-0.5.00/tests/CMakeLists.txt000066400000000000000000000333011353046746100164370ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen # ============================================================================== # Generate a pair of randomly named directories # string(RANDOM LENGTH 4 ALPHABET "0123456789" _random) set(_random "cmake") set(_tests_data_dir "${CMAKE_CURRENT_BINARY_DIR}/data_${_random}") set(_tests_out_dir "${CMAKE_CURRENT_BINARY_DIR}/out_${_random}") add_custom_command( OUTPUT ${_tests_data_dir} ${_tests_out_dir} COMMAND ${CMAKE_COMMAND} -E make_directory "${_tests_data_dir}" COMMAND ${CMAKE_COMMAND} -E make_directory "${_tests_out_dir}" ) # ============================================================================== # Main helper variables set(_test_groups) set(_test_list_data) set(_data_file_list) set(_data_cmd_list) # ============================================================================== # This macro parses a XXX.mk file and extracts its tests and related commands # # Each call to this macro appends a new group to the _test_groups list # For each group XXX, a variable _test_list_XXX is created to store the names # of the tests present in that group. # For each test TTT in group XXX, a variable TEST_XXX_TTT contains the list of # commands to execute for that particular test macro(parse_test_file filename) # First get name of the group and add it to the global list get_filename_component(_group ${filename} NAME_WE) list(APPEND _test_groups ${_group}) set(_test_list_${_group}) # Read the file file(READ ${filename} _test_file_lines) string(REPLACE "\\" ";;" _test_file_lines ${_test_file_lines}) string(REPLACE "\n" ";;" _test_file_lines ${_test_file_lines}) # The following algorithm is relying on the fact that we first encounter a line # with the test name (of the form tests/test-name:) and then a series of # tab-indented lines that start with $(TOOLDIR)/some-command + arguments set(_curr_test) foreach(_line ${_test_file_lines}) string(STRIP ${_line} _is_empty) if(NOT ${_is_empty} STREQUAL "") # Look for $(TOOLDIR) to find out if a line is a command or not string(FIND ${_line} "$(TOOLDIR)" _is_cmd) # Try to grab the test name string(REGEX MATCH "^tests/([^:]+)" _test_name ${_line}) if(NOT "${_test_name}" STREQUAL "") # Got the name -> remove tests/ from the beginning of the string string(SUBSTRING ${_test_name} 6 -1 _test_name) string(REPLACE "-" "_" _test_name ${_test_name}) # Add this test to the list of test for this group list(APPEND _test_list_${_group} ${_test_name}) set(_curr_test ${_test_name}) elseif(_is_cmd GREATER -1 AND NOT _curr_test STREQUAL "") # First chars are TAB + $ -> command part of a test # Separate line by whitespace string(REPLACE " " ";" _comp ${_line}) set(_cmd) foreach(_c ${_comp}) # Starts with "\t$(TOOLDIR)" => it's the name of the command string(REGEX MATCH "^\t\\$\\(TOOLDIR\\)/([a-zA-z0-9]+)" _cmd_name ${_c}) # Contains $(TESTS_OUT) => path to an input file in data diretory string(REGEX MATCH "\\$\\(TESTS_OUT\\)/(.*)" _path ${_c}) if(NOT ${_cmd_name} STREQUAL "") string(REPLACE "$(TOOLDIR)/" " $ " _cmd_name ${_cmd_name}) set(_cmd "${_cmd} ${_cmd_name}") elseif(NOT ${_path} STREQUAL "") string(REPLACE "$(TESTS_OUT)/" "${_tests_data_dir}/" _path ${_path}) file(TO_NATIVE_PATH ${_path} _path) set(_cmd "${_cmd} ${_path}") else() set(_cmd "${_cmd} ${_c}") endif() endforeach() # If we were called with some extra arguments, apply an extra processing # step to the command before adding it to the list if(${ARGC} GREATER 1) _parse_cmdline_custom(${_cmd} ${ARGN}) endif() # Cleanup string and add it to the list of commands for the current test string(STRIP ${_cmd} _cmd) list(APPEND TEST_${_group}_${_curr_test} ${_cmd}) endif() else() # Reset current test name if we encounter anything else set(_curr_test) endif() endforeach() endmacro() # ------------------------------------------------------------------------------ # This macro parses a XXX.mk file and extracts the commands that generate some # test data # # Each call to this macro may append some name XXX to the list of data files # (_test_list_data). If a new test data file is found, then the command needed # to generate the file is saved in the _data_XXX_cmd variable and the path to # the file in the _data_XXX_file variable. # Also, if the generation of the current data file is dependent on another one, # the variable _data_XXX_deps will contain the file that needs to be created # first. macro(parse_test_file_for_data filename) # First read the file file(READ ${filename} _test_file_lines) string(REPLACE "\\" ";" _test_file_lines ${_test_file_lines}) string(REPLACE "\n" ";" _test_file_lines ${_test_file_lines}) set(_data_name) set(_data_cmd) foreach(_line ${_test_file_lines}) string(STRIP ${_line} _is_empty) string(LENGTH ${_line} _str_length) if(NOT ${_is_empty} STREQUAL "" AND _str_length GREATER 12) string(SUBSTRING "${_line}" 0 12 _name_header) string(SUBSTRING "${_line}" 0 2 _cmd_header) if(_name_header STREQUAL "$(TESTS_OUT)") # Found a name line -> extract the name and add it to the list of names string(REGEX MATCH "\\$\\(TESTS_OUT\\)/([^:]+)" _data_name ${_line}) string(REPLACE "$(TESTS_OUT)/" "" _data_name ${_data_name}) get_filename_component(_bname ${_data_name} NAME_WE) list(APPEND _test_list_data ${_bname}) set(_data_cmd) elseif(_data_name AND NOT _data_cmd AND ${_cmd_header} STREQUAL "\t$") # Got a command line -> parse it and save the command string(REPLACE "$(TOOLDIR)/" "$ " _data_cmd ${_line}) # If the line contains $(TESTS_OUT) we have a dependency string(REGEX MATCH "\\$\\(TESTS_OUT\\)/([^ \t]+)" _data_deps ${_data_cmd}) if(NOT _data_deps STREQUAL "") # Modify the command to have the correct path string(REPLACE "$(TESTS_OUT)/" "${_tests_data_dir}/" _data_cmd ${_data_cmd}) # Cleanup the dependency name and save it string(REPLACE "$(TESTS_OUT)/" "" _data_deps ${_data_deps}) set(_data_${_bname}_deps "${_tests_data_dir}/${_data_deps}") endif() # Cleanup command line and then save it string(REPLACE "$@" "${_data_name}" _data_cmd ${_data_cmd}) string(STRIP ${_data_cmd} _data_${_bname}_cmd) # Propery set the name of the data file and save it file(TO_NATIVE_PATH "${_tests_data_dir}/${_data_name}" _data_file) set(_data_${_bname}_file ${_data_file}) else() set(_data_name) set(_data_cmd) set(_bname) endif() endif() endforeach() endmacro() # ------------------------------------------------------------------------------ # This macro processes the list of test data files to be generated and creates # custom commands to generate them. # # We simply iterate over the list of data files, grab the required information # and then generate a file to create the CMake custom command macro(add_commands_for_test_data_generation) foreach(_data_name ${_test_list_data}) # Set relevant helper variables set(TEST_DATA_OUTPUT ${_data_${_data_name}_file}) set(TEST_DATA_CMD ${_data_${_data_name}_cmd}) set(TEST_DATA_DEPS ${_tests_data_dir};${_data_${_data_name}_deps}) set(TEST_DATA_DIR ${_tests_data_dir}) # Generate the file... configure_file(${PROJECT_SOURCE_DIR}/cmake/tests_data_generation.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/tests_datagen_${_data_name}.cmake @ONLY) # ...and include it include(${CMAKE_CURRENT_BINARY_DIR}/tests_datagen_${_data_name}.cmake) file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/tests_datagen_${_data_name}.cmake) # While we're at it also keep a list of all the test data files list(APPEND _data_file_list ${_data_${_data_name}_file}) endforeach() endmacro() # ------------------------------------------------------------------------------ # This macro processes the list of tests for a particular group and generates # a CMake script file in order to execute them macro(create_integration_test group) # First, create a custom target to execute all the test in the group set(_grp_test_tgt integration_${group}) add_custom_target(${_grp_test_tgt} DEPENDS ${_data_file_list}) # Then iterate over all the tests in the group foreach(_test ${_test_list_${group}}) # Skip GPU-related test if we did not compile with CUDA support string(REGEX MATCH ".*gpu.*" _test_require_gpu ${_test}) if(USE_CUDA OR _test_require_gpu STREQUAL "") # Build the CMake script file content set(_cmd_list "set(_error_flag 0)\n") list(APPEND _cmd_list "execute_process(COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --blue \"Executing ${_test}\")\n") foreach(_cmd ${TEST_${group}_${_test}}) set(_exec_in) # Set environment variables before calling the command if required if(NOT ${_test_${group}_env_name} STREQUAL "") foreach(_name ${_test_${group}_env_name}) set(_exec_in "${_exec_in}\nset(ENV{${_name}} \"${_test_${group}_env_val}\")") endforeach() endif() string(REPLACE "\"" "\\\"" _cmd_escaped ${_cmd}) # For each command in the test, we make a call execute_process() set(_exec_in "${_exec_in}\nexecute_process(\nCOMMAND ${_cmd}\nRESULT_VARIABLE res_var\nWORKING_DIRECTORY ${_tests_out_dir}\nOUTPUT_VARIABLE _output\nERROR_VARIABLE _output)\nif(NOT \"\${res_var}\" STREQUAL \"0\")\n message(ERROR \"Command ${_cmd_escaped} failed with return \${res_var}:\\n \${_output} \")\nset(_error_flag 1)\nendif()\n\n") list(APPEND _cmd_list "${_exec_in}") endforeach() list(APPEND _cmd_list "if(_error_flag)\nexecute_process(COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red \"FAILED\")\nelse()\nexecute_process(COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --green \"PASSED\")\nendif()\n") string(REPLACE ";" "\n" _cmd_list ${_cmd_list}) # Finally, we write the file... file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_test}.cmake CONTENT "${_cmd_list}") # ...and create a target to execute it. add_custom_command(TARGET ${_grp_test_tgt} POST_BUILD COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/${_test}.cmake) endif() endforeach() endmacro() # ============================================================================== # Macro to handle some special cases set(_python_cmd_match "python") macro(_parse_cmdline_custom cmd type) if(${type} STREQUAL ${_python_cmd_match}) string(REGEX MATCH "PYTHONPATH.*" _is_python ${cmd}) if(NOT _is_python STREQUAL "") string(REGEX REPLACE "PYTHONPATH[^ \t]+(.*)" "${Python_EXECUTABLE}\\1" _cmd "${cmd}") string(REGEX REPLACE "\\$\\(TOOLDIR\\)/(.*)" "${PROJECT_SOURCE_DIR}/\\1" _cmd "${_cmd}") endif() endif() endmacro() # ============================================================================== # Macros to manually add some tests (ie. not based on some *.mk file) macro(add_new_test_group group) list(APPEND _test_groups ${group}) endmacro() macro(add_test_to_group group test_name) list(APPEND _test_list_${group} ${test_name}) set(TEST_${group}_${test_name} ${ARGN}) endmacro() macro(add_env_var_to_group group name value) set(_test_${group}_env_name "${name}") set(_test_${group}_env_val "${value}") endmacro() # ============================================================================== # Now that we have all our macros, we simply iterate over all the XXX.mk files # in the folder, while skipping some incompatible tests # - join: calls commands like `seq 1 300` which may not work if not on Linux # - estdelay: one call to `$(TOOLDIR)/estdelay` in the middle of another # command -> impossible to do with the current approach # # NB: the GPU-only tests are already ignored when parsing the tests file # since they all contain the "gpu" string in their name file(GLOB _file_list ${CMAKE_CURRENT_LIST_DIR}/*.mk) foreach(_file ${_file_list}) get_filename_component(_bname ${_file} NAME_WE) if(_bname MATCHES "python") if(CMAKE_VERSION VERSION_LESS 3.12) find_package(BPython ${_python_version} QUIET COMPONENTS Interpreter) else() find_package(Python ${_python_version} QUIET COMPONENTS Interpreter) endif() if(Python_FOUND) set(_test_${_bname}_env_name "PYTHONPATH") if(WIN32) set(_test_${_bname}_env_val "${PROJECT_SOURCE_DIR}/python;$ENV{PYTHONPATH}") else() set(_test_${_bname}_env_val "${PROJECT_SOURCE_DIR}/python:$ENV{PYTHONPATH}") endif() parse_test_file(${_file} ${_python_cmd_match}) else() message(WARNING "Python interpreter not found: unable to perform python test") endif() elseif(_bname STREQUAL "join" OR _bname STREQUAL "estdelay") # Do nothing else() parse_test_file_for_data(${_file}) parse_test_file(${_file}) endif() endforeach() if(BART_CREATE_PYTHON_MODULE) if(CMAKE_VERSION VERSION_LESS 3.12) find_package(BPython ${_python_version} QUIET COMPONENTS Interpreter) else() find_package(Python ${_python_version} QUIET COMPONENTS Interpreter) endif() if(Python_FOUND) include(${CMAKE_CURRENT_LIST_DIR}/pyBART.cmake) else() message(WARNING "Python interpreter not found: unable to perform pyBART test") endif() endif() add_commands_for_test_data_generation() # ============================================================================== # Finally add conveniene targets to launch all tests add_custom_target(integration) foreach(_group ${_test_groups}) create_integration_test(${_group}) add_dependencies(integration integration_${_group}) endforeach() add_custom_target(integration_clean COMMAND ${CMAKE_COMMAND} -E remove_directory ${_tests_data_dir} COMMAND ${CMAKE_COMMAND} -E remove_directory ${_tests_out_dir} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) bart-0.5.00/tests/casorati.mk000066400000000000000000000012001353046746100160260ustar00rootroot00000000000000 tests/test-casorati: ones noise casorati reshape avg slice squeeze extract nrmse set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 6 6 o1.ra ;\ $(TOOLDIR)/noise o1.ra o2.ra ;\ $(TOOLDIR)/casorati 1 2 o2.ra o3.ra ;\ $(TOOLDIR)/reshape 7 5 6 2 o3.ra o4.ra ;\ $(TOOLDIR)/avg 4 o4.ra o5.ra ;\ $(TOOLDIR)/slice 0 1 o5.ra o6.ra ;\ $(TOOLDIR)/squeeze o6.ra o7.ra ;\ $(TOOLDIR)/extract 1 1 3 o2.ra i2.ra ;\ $(TOOLDIR)/avg 2 i2.ra i3.ra ;\ $(TOOLDIR)/nrmse -t 0.001 i3.ra o7.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-casorati bart-0.5.00/tests/cc.mk000066400000000000000000000037461353046746100146270ustar00rootroot00000000000000 tests/test-cc-svd: cc resize nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -S -p 8 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc8.ra ;\ $(TOOLDIR)/cc -S -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc4.ra ;\ $(TOOLDIR)/resize 3 8 ksp-cc4.ra ksp-cc-z.ra ;\ $(TOOLDIR)/nrmse -t 0.1 ksp-cc8.ra ksp-cc-z.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-cc-geom: cc rss resize nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -G -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc4.ra ;\ $(TOOLDIR)/rss 11 ksp-cc4.ra ksp0-cc4.ra ;\ $(TOOLDIR)/rss 11 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp0.ra ;\ $(TOOLDIR)/nrmse -t 0.0001 ksp0.ra ksp0-cc4.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-cc-esp: cc rss resize nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -E -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc4.ra ;\ $(TOOLDIR)/resize 3 8 ksp-cc4.ra ksp-cc-z.ra ;\ $(TOOLDIR)/rss 11 ksp-cc4.ra ksp0-cc4.ra ;\ $(TOOLDIR)/rss 11 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp0.ra ;\ $(TOOLDIR)/nrmse -t 0.0001 ksp0.ra ksp0-cc4.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-cc-svd-matrix: cc extract fmac transpose nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -S -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc.ra ;\ $(TOOLDIR)/cc -M -S $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/extract 4 0 4 sccmat.ra sccmat-4.ra ;\ $(TOOLDIR)/fmac -C -s 8 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat-4.ra ksp-cc-3.ra ;\ $(TOOLDIR)/transpose 3 4 ksp-cc-3.ra ksp-cc-4.ra ;\ $(TOOLDIR)/nrmse -t 0.001 ksp-cc.ra ksp-cc-4.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-cc-svd tests/test-cc-geom tests/test-cc-esp tests/test-cc-svd-matrix bart-0.5.00/tests/ccapply.mk000066400000000000000000000066331353046746100156730ustar00rootroot00000000000000 tests/test-ccapply-forward: cc ccapply nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -S -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc.ra ;\ $(TOOLDIR)/cc -M -S $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/ccapply -S -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ksp-cc-2.ra ;\ $(TOOLDIR)/nrmse -t 0.001 ksp-cc.ra ksp-cc-2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ccapply-backward: cc ccapply extract fmac transpose nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -M -S $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/ccapply -S -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ksp-cc.ra ;\ $(TOOLDIR)/ccapply -S -u ksp-cc.ra sccmat.ra ksp-2.ra ;\ $(TOOLDIR)/extract 4 0 4 sccmat.ra sccmat-4.ra ;\ $(TOOLDIR)/transpose 3 4 ksp-cc.ra ksp-ccT.ra ;\ $(TOOLDIR)/fmac -s 16 ksp-ccT.ra sccmat-4.ra ksp-3.ra ;\ $(TOOLDIR)/nrmse -t 0.08 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-2.ra ;\ $(TOOLDIR)/nrmse -t 0.0001 ksp-2.ra ksp-3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ccapply-geom-forward: cc ccapply extract nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -G -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc.ra ;\ $(TOOLDIR)/cc -M -p 4 -G $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/ccapply -G -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ksp-cc-2.ra ;\ $(TOOLDIR)/extract 4 0 4 sccmat.ra sccmat-4.ra ;\ $(TOOLDIR)/nrmse -t 0.001 ksp-cc.ra ksp-cc-2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ccapply-geom-backward: cc ccapply nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -M -p4 -G $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/ccapply -G -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ksp-cc.ra ;\ $(TOOLDIR)/ccapply -G -u ksp-cc.ra sccmat.ra ksp-2.ra ;\ $(TOOLDIR)/nrmse -t 0.08 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ccapply-esp-forward: cc ccapply extract nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -E -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc.ra ;\ $(TOOLDIR)/cc -M -p 4 -E $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/ccapply -E -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ksp-cc-2.ra ;\ $(TOOLDIR)/extract 4 0 4 sccmat.ra sccmat-4.ra ;\ $(TOOLDIR)/nrmse -t 0.001 ksp-cc.ra ksp-cc-2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ccapply-esp-backward: cc ccapply nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -M -p4 -E $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ;\ $(TOOLDIR)/ccapply -E -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra sccmat.ra ksp-cc.ra ;\ $(TOOLDIR)/ccapply -E -u ksp-cc.ra sccmat.ra ksp-2.ra ;\ $(TOOLDIR)/nrmse -t 0.08 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-ccapply-forward tests/test-ccapply-backward TESTS += tests/test-ccapply-geom-forward tests/test-ccapply-geom-backward TESTS += tests/test-ccapply-esp-forward tests/test-ccapply-esp-backward bart-0.5.00/tests/cdf97.mk000066400000000000000000000005401353046746100151430ustar00rootroot00000000000000 tests/test-cdf97: cdf97 nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cdf97 3 $(TESTS_OUT)/shepplogan.ra w.ra ;\ $(TOOLDIR)/cdf97 -i 3 w.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 $(TESTS_OUT)/shepplogan.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-cdf97 bart-0.5.00/tests/copy.mk000066400000000000000000000021001353046746100151730ustar00rootroot00000000000000 tests/test-copy: ones copy nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 50 50 a.ra ;\ $(TOOLDIR)/copy a.ra b.ra ;\ $(TOOLDIR)/nrmse -t 0. a.ra b.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-copy-out: ones zeros copy resize nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 50 50 o.ra ;\ $(TOOLDIR)/resize -c 0 100 1 100 o.ra o0.ra ;\ $(TOOLDIR)/zeros 2 50 50 o1.ra ;\ $(TOOLDIR)/copy 0 25 1 25 o0.ra o1.ra ;\ $(TOOLDIR)/nrmse -t 0. o1.ra o.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-copy-in: ones zeros copy resize nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 50 50 o.ra ;\ $(TOOLDIR)/resize -c 0 100 1 100 o.ra o0.ra ;\ $(TOOLDIR)/zeros 2 100 100 o1.ra ;\ $(TOOLDIR)/copy 0 25 1 25 o.ra o1.ra ;\ $(TOOLDIR)/nrmse -t 0. o1.ra o0.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-copy tests/test-copy-out tests/test-copy-in bart-0.5.00/tests/ecalib.mk000066400000000000000000000041331353046746100154500ustar00rootroot00000000000000 tests/test-ecalib: ecalib pocsense nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ecalib -m1 $(TESTS_OUT)/shepplogan_coil_ksp.ra coils.ra ;\ $(TOOLDIR)/pocsense -i1 $(TESTS_OUT)/shepplogan_coil_ksp.ra coils.ra proj.ra ;\ $(TOOLDIR)/nrmse -t 0.05 proj.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ecalib-auto: ecalib pocsense nrmse noise $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/noise -n 100 $(TESTS_OUT)/shepplogan_coil_ksp.ra shepplogan_noise.ra ;\ $(TOOLDIR)/ecalib -m 1 -a -v 100 shepplogan_noise.ra coils.ra ;\ $(TOOLDIR)/pocsense -i 1 shepplogan_noise.ra coils.ra proj.ra ;\ $(TOOLDIR)/nrmse -t 0.035 $(TESTS_OUT)/shepplogan_coil_ksp.ra proj.ra;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ecalib-rotation: ecalib cc nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/cc -S -p 4 $(TESTS_OUT)/shepplogan_coil_ksp.ra ksp-cc.ra ;\ $(TOOLDIR)/ecalib -m1 ksp-cc.ra scc-sens.ra ;\ $(TOOLDIR)/ecalib -P -m1 ksp-cc.ra scc-sens2.ra ;\ $(TOOLDIR)/nrmse -s -t 0.000001 scc-sens.ra scc-sens2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-ecalib-rotation2: ecalib cc fmac transpose nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ecalib -m1 $(TESTS_OUT)/shepplogan_coil_ksp.ra sens.ra ;\ $(TOOLDIR)/cc -M -S $(TESTS_OUT)/shepplogan_coil_ksp.ra cc-mat.ra ;\ $(TOOLDIR)/fmac -C -s 8 $(TESTS_OUT)/shepplogan_coil_ksp.ra cc-mat.ra ksp-cc.ra ;\ $(TOOLDIR)/transpose 3 4 ksp-cc.ra ksp-cc-2.ra ;\ $(TOOLDIR)/ecalib -P -m1 ksp-cc-2.ra scc-sens-1.ra ;\ $(TOOLDIR)/transpose 3 4 scc-sens-1.ra scc-sens-2.ra ;\ $(TOOLDIR)/fmac -s 16 scc-sens-2.ra cc-mat.ra scc-sens.ra ;\ $(TOOLDIR)/nrmse -t 0.1 sens.ra scc-sens.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-ecalib tests/test-ecalib-auto tests/test-ecalib-rotation TESTS += tests/test-ecalib-rotation2 bart-0.5.00/tests/estdelay.mk000066400000000000000000000045501353046746100160460ustar00rootroot00000000000000 tests/test-estdelay: estdelay traj phantom nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -D -q1.5:1:-0.5 -r -y8 t.ra ;\ $(TOOLDIR)/phantom -k -t t.ra k.ra ;\ $(TOOLDIR)/traj -D -q`$(TOOLDIR)/estdelay t.ra k.ra` -r -y8 t2.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 t.ra t2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-estdelay-transverse: estdelay traj phantom nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -D -O -q1.5:1:-0.5 -r -y8 t.ra ;\ $(TOOLDIR)/phantom -k -t t.ra k.ra ;\ $(TOOLDIR)/traj -D -O -q`$(TOOLDIR)/estdelay t.ra k.ra` -r -y8 t2.ra ;\ $(TOOLDIR)/nrmse -t 0.001 t.ra t2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-estdelay-coils: estdelay scale traj phantom nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -G -q0.3:-0.1:0.2 -y5 t.ra ;\ $(TOOLDIR)/traj -G -r -y5 n.ra ;\ $(TOOLDIR)/scale 0.5 n.ra ns.ra ;\ $(TOOLDIR)/scale 0.5 t.ra ts.ra ;\ $(TOOLDIR)/phantom -s8 -k -t ts.ra k.ra ;\ $(TOOLDIR)/traj -G -q`$(TOOLDIR)/estdelay ns.ra k.ra` -y5 t2.ra ;\ $(TOOLDIR)/nrmse -t 0.004 t.ra t2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-estdelay-ring: estdelay scale traj phantom nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -G -q0.3:-0.1:0.2 -c -y5 t.ra ;\ $(TOOLDIR)/traj -G -c -r -y5 n.ra ;\ $(TOOLDIR)/scale 0.5 n.ra ns.ra ;\ $(TOOLDIR)/scale 0.5 t.ra ts.ra ;\ $(TOOLDIR)/phantom -k -t ts.ra k.ra ;\ $(TOOLDIR)/traj -G -q`$(TOOLDIR)/estdelay -R ns.ra k.ra` -c -y5 t2.ra ;\ $(TOOLDIR)/nrmse -t 0.003 t.ra t2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-estdelay-scale: estdelay scale traj phantom nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -D -q1.5:1:-0.5 -r -y8 t.ra ;\ $(TOOLDIR)/scale 0.5 t.ra ts.ra ;\ $(TOOLDIR)/phantom -k -t ts.ra k.ra ;\ $(TOOLDIR)/traj -D -q`$(TOOLDIR)/estdelay ts.ra k.ra` -r -y8 t2.ra ;\ $(TOOLDIR)/scale 0.5 t2.ra t2s.ra ;\ $(TOOLDIR)/nrmse -t 0.0001 ts.ra t2s.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-estdelay tests/test-estdelay-transverse TESTS += tests/test-estdelay-ring tests/test-estdelay-coils tests/test-estdelay-scale bart-0.5.00/tests/estshift.mk000066400000000000000000000006541353046746100160660ustar00rootroot00000000000000 tests/test-estshift: estshift ones resize flip set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 1 o.ra ;\ $(TOOLDIR)/resize -c 0 100 o.ra o0.ra ;\ $(TOOLDIR)/flip 1 o0.ra o1.ra ;\ $(TOOLDIR)/estshift 1 o1.ra o1.ra | grep "0.000000" ;\ $(TOOLDIR)/estshift 1 o0.ra o1.ra | grep "1.000000" ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-estshift bart-0.5.00/tests/extract.mk000066400000000000000000000014541353046746100157060ustar00rootroot00000000000000 tests/test-extract: ones extract resize nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 10 10 o.ra ;\ $(TOOLDIR)/resize -c 0 100 1 100 o.ra o0.ra ;\ $(TOOLDIR)/extract 1 45 55 o0.ra o1.ra ;\ $(TOOLDIR)/extract 0 45 55 o1.ra o2.ra ;\ $(TOOLDIR)/nrmse -t 0. o2.ra o.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-extract-multidim: ones extract resize nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 10 10 10 o.ra ;\ $(TOOLDIR)/resize -c 0 100 1 100 2 100 o.ra o0.ra ;\ $(TOOLDIR)/extract 0 45 55 1 45 55 2 45 55 o0.ra o1.ra ;\ $(TOOLDIR)/nrmse -t 0. o1.ra o.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-extract tests/test-extract-multidim bart-0.5.00/tests/fft.mk000066400000000000000000000031011353046746100150020ustar00rootroot00000000000000 # basic 2D FFT $(TESTS_OUT)/shepplogan_fft.ra: fft $(TESTS_OUT)/shepplogan.ra $(TOOLDIR)/fft 7 $(TESTS_OUT)/shepplogan.ra $@ tests/test-fft-basic: scale fft nrmse $(TESTS_OUT)/shepplogan_fft.ra $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/scale 16384 $(TESTS_OUT)/shepplogan.ra shepploganS.ra ;\ $(TOOLDIR)/fft -i 7 $(TESTS_OUT)/shepplogan_fft.ra shepplogan2.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 shepploganS.ra shepplogan2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # unitary FFT $(TESTS_OUT)/shepplogan_fftu.ra: fft $(TESTS_OUT)/shepplogan.ra $(TOOLDIR)/fft -u 7 $(TESTS_OUT)/shepplogan.ra $@ tests/test-fft-unitary: fft nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_fftu.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fft -u -i 7 $(TESTS_OUT)/shepplogan_fftu.ra shepplogan2u.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 $(TESTS_OUT)/shepplogan.ra shepplogan2u.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # uncentered FFT tests/test-fft-uncentered: fftmod fft nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_fftu.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fftmod -i 7 $(TESTS_OUT)/shepplogan_fftu.ra shepplogan_fftu2.ra ;\ $(TOOLDIR)/fft -uni 7 shepplogan_fftu2.ra shepplogan2u.ra ;\ $(TOOLDIR)/fftmod -i 7 shepplogan2u.ra shepplogan3u.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 $(TESTS_OUT)/shepplogan.ra shepplogan3u.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-fft-basic tests/test-fft-unitary tests/test-fft-uncentered bart-0.5.00/tests/filter.mk000066400000000000000000000014631353046746100155210ustar00rootroot00000000000000 tests/test-filter-median: index filter extract nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/index 2 10 a.ra ;\ $(TOOLDIR)/filter -m2 -l5 a.ra b.ra ;\ $(TOOLDIR)/extract 2 2 8 a.ra c.ra ;\ $(TOOLDIR)/nrmse -t 0. c.ra b.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-filter-median2: index filter extract nrmse repmat set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/index 1 10 a.ra ;\ $(TOOLDIR)/repmat 0 13 a.ra a0.ra ;\ $(TOOLDIR)/repmat 2 11 a0.ra a2.ra ;\ $(TOOLDIR)/filter -m1 -l5 a2.ra b.ra ;\ $(TOOLDIR)/extract 1 2 8 a2.ra c.ra ;\ $(TOOLDIR)/nrmse -t 0. c.ra b.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-filter-median tests/test-filter-median2 bart-0.5.00/tests/flatten.mk000066400000000000000000000006331353046746100156670ustar00rootroot00000000000000 tests/test-flatten: ones reshape flatten noise nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 6 1 2 1 3 1 4 a0.ra ;\ $(TOOLDIR)/noise a0.ra a1.ra ;\ $(TOOLDIR)/flatten a1.ra a2.ra ;\ $(TOOLDIR)/reshape 63 24 1 1 1 1 1 a1.ra a3.ra ;\ $(TOOLDIR)/nrmse -t 0. a2.ra a3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-flatten bart-0.5.00/tests/fmac.mk000066400000000000000000000006511353046746100151400ustar00rootroot00000000000000 tests/test-fmac-sum: ones fmac noise nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 2 1 3 a0.ra ;\ $(TOOLDIR)/noise a0.ra a1.ra ;\ $(TOOLDIR)/fmac -s 4 a1.ra a2.ra ;\ $(TOOLDIR)/ones 1 1 o.ra ;\ $(TOOLDIR)/fmac -s 4 a1.ra o.ra a3.ra ;\ $(TOOLDIR)/nrmse -t 0. a2.ra a3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-fmac-sum bart-0.5.00/tests/gpu.mk000066400000000000000000000047251353046746100150330ustar00rootroot00000000000000 # tests/test-pics-gpu: pics nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/pics -g -S -r0.001 $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco1.ra ;\ $(TOOLDIR)/pics -S -r0.001 $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-gpu-noncart: traj scale phantom ones pics nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y64 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -S -r0.001 -t traj2.ra ksp.ra o.ra reco1.ra ;\ $(TOOLDIR)/pics -g -S -r0.001 -t traj2.ra ksp.ra o.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.001 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-gpu-weights: pics scale ones nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 128 128 weights.ra ;\ $(TOOLDIR)/scale 0.1 weights.ra weights2.ra ;\ $(TOOLDIR)/pics -S -r0.001 -p weights2.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco1.ra ;\ $(TOOLDIR)/pics -g -S -r0.001 -p weights2.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 reco2.ra reco1.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # similar to the non-gpu test this had to be relaxed to 0.01 tests/test-pics-gpu-noncart-weights: traj scale ones phantom pics nrmse $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y32 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -s8 -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 4 1 256 32 1 weights.ra ;\ $(TOOLDIR)/scale 0.1 weights.ra weights2.ra ;\ $(TOOLDIR)/pics -S -r0.001 -p weights2.ra -t traj2.ra ksp.ra $(TESTS_OUT)/coils.ra reco1.ra ;\ $(TOOLDIR)/pics -g -S -r0.001 -p weights2.ra -t traj2.ra ksp.ra $(TESTS_OUT)/coils.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.010 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS_GPU += tests/test-pics-gpu tests/test-pics-gpu-noncart TESTS_GPU += tests/test-pics-gpu-weights tests/test-pics-gpu-noncart-weights bart-0.5.00/tests/homodyne.mk000066400000000000000000000026431353046746100160570ustar00rootroot00000000000000 tests/test-homodyne: fft rss ones zeros join fmac homodyne nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fft -iu 3 $(TESTS_OUT)/shepplogan_coil_ksp.ra c0.ra ;\ $(TOOLDIR)/rss 8 c0.ra r0.ra ;\ $(TOOLDIR)/ones 2 128 96 o.ra ;\ $(TOOLDIR)/zeros 2 128 32 z.ra ;\ $(TOOLDIR)/join 1 o.ra z.ra oz.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan_coil_ksp.ra oz.ra k1.ra ;\ $(TOOLDIR)/homodyne -C 1 .75 k1.ra c1.ra ;\ $(TOOLDIR)/rss 8 c1.ra r1.ra ;\ $(TOOLDIR)/nrmse -t 0.02 r0.ra r1.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-homodyne-fftu: ones zeros join fmac homodyne rss fft fftmod nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 128 96 o.ra ;\ $(TOOLDIR)/zeros 2 128 32 z.ra ;\ $(TOOLDIR)/join 1 o.ra z.ra oz.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan_coil_ksp.ra oz.ra k1.ra ;\ $(TOOLDIR)/homodyne -C 1 .75 k1.ra c1.ra ;\ $(TOOLDIR)/rss 8 c1.ra r1.ra ;\ $(TOOLDIR)/fft -iu 3 k1.ra c1.ra ;\ $(TOOLDIR)/fftmod 3 c1.ra c1f.ra ;\ $(TOOLDIR)/homodyne -n -I -C 1 .75 c1f.ra c1h.ra ;\ $(TOOLDIR)/rss 8 c1h.ra r2.ra ;\ $(TOOLDIR)/nrmse -t 0.001 r1.ra r2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-homodyne tests/test-homodyne-fftu bart-0.5.00/tests/itsense.mk000066400000000000000000000010661353046746100157050ustar00rootroot00000000000000 tests/test-itsense: itsense scale pattern nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/pattern $(TESTS_OUT)/shepplogan_coil_ksp.ra pat.ra ;\ $(TOOLDIR)/itsense 0.001 $(TESTS_OUT)/coils.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra pat.ra reco.ra ;\ $(TOOLDIR)/scale 128. reco.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.23 reco2.ra $(TESTS_OUT)/shepplogan.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-itsense bart-0.5.00/tests/join.mk000066400000000000000000000021551353046746100151720ustar00rootroot00000000000000 tests/test-join: ones join nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ seq 1 300 | xargs -P 100 -n1 -I {} $(TOOLDIR)/ones 3 6 1 7 o-{}.ra ;\ $(TOOLDIR)/ones 3 6 300 7 o1.ra ;\ $(TOOLDIR)/join 1 o-*.ra o.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 o.ra o1.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-join-append: ones zeros join nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 6 7 1 o ;\ $(TOOLDIR)/zeros 3 6 7 1 z ;\ $(TOOLDIR)/join 2 o z o j ;\ $(TOOLDIR)/join -a 2 z o o ;\ $(TOOLDIR)/nrmse -t 0.00001 j o ;\ rm *.cfl ; rm *.hdr ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-join-append-one: ones zeros join nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 6 7 1 o ;\ $(TOOLDIR)/zeros 3 6 7 1 z ;\ $(TOOLDIR)/join 2 o z j ;\ $(TOOLDIR)/join -a 2 o z x ;\ $(TOOLDIR)/nrmse -t 0.00001 j x ;\ rm *.cfl ; rm *.hdr ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-join tests/test-join-append tests/test-join-append-one bart-0.5.00/tests/linsub.mk000066400000000000000000000063271353046746100155340ustar00rootroot00000000000000 $(TESTS_OUT)/exponentials.ra: index fmac scale zexp set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/index 0 128 i.ra ;\ $(TOOLDIR)/index 6 32 i2.ra ;\ $(TOOLDIR)/fmac i.ra i2.ra i3.ra ;\ $(TOOLDIR)/scale -- -0.001 i3.ra i4.ra ;\ $(TOOLDIR)/zexp i4.ra $@ ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) $(TESTS_OUT)/phantom-exp.ra: phantom fmac $(TESTS_OUT)/exponentials.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/phantom x.ra ;\ $(TOOLDIR)/fmac x.ra $(TESTS_OUT)/exponentials.ra $@ ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) $(TESTS_OUT)/expon-basis.ra: squeeze svd transpose extract reshape $(TESTS_OUT)/exponentials.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/squeeze $(TESTS_OUT)/exponentials.ra es.ra ;\ $(TOOLDIR)/svd es.ra u.ra s.ra v.ra ;\ $(TOOLDIR)/transpose 0 1 v.ra vT.ra ;\ $(TOOLDIR)/extract 1 0 4 vT.ra v2.ra ;\ $(TOOLDIR)/reshape 99 1 1 32 4 v2.ra $@ ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) tests/test-pics-linsub: fft reshape ones delta repmat reshape fmac pics transpose nrmse $(TESTS_OUT)/phantom-exp.ra $(TESTS_OUT)/expon-basis.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fft -u 7 $(TESTS_OUT)/phantom-exp.ra xek.ra ;\ $(TOOLDIR)/reshape 96 32 1 xek.ra xek2.ra ;\ $(TOOLDIR)/ones 2 128 128 o.ra ;\ $(TOOLDIR)/delta 8 33 8 p.ra ;\ $(TOOLDIR)/repmat 1 16 p.ra p2.ra ;\ $(TOOLDIR)/repmat 6 4 p2.ra p3.ra ;\ $(TOOLDIR)/reshape 3 128 1 p3.ra p4.ra ;\ $(TOOLDIR)/reshape 96 32 1 p4.ra p5.ra ;\ $(TOOLDIR)/fmac xek2.ra p5.ra xek3.ra ;\ $(TOOLDIR)/repmat 1 128 p5.ra p6.ra ;\ $(TOOLDIR)/pics -w1. -B$(TESTS_OUT)/expon-basis.ra -pp6.ra xek3.ra o.ra x2.ra ;\ $(TOOLDIR)/fmac -s 64 x2.ra $(TESTS_OUT)/expon-basis.ra xx.ra ;\ $(TOOLDIR)/transpose 5 6 xx.ra xxT.ra ;\ $(TOOLDIR)/nrmse -t 0.001 $(TESTS_OUT)/phantom-exp.ra xxT.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-linsub-noncart: traj scale nufft reshape ones delta repmat reshape fmac pics transpose nrmse $(TESTS_OUT)/phantom-exp.ra $(TESTS_OUT)/expon-basis.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y128 t.ra ;\ $(TOOLDIR)/scale 0.5 t.ra t2.ra ;\ $(TOOLDIR)/nufft t2.ra $(TESTS_OUT)/phantom-exp.ra xek.ra ;\ $(TOOLDIR)/reshape 96 32 1 xek.ra xek2.ra ;\ $(TOOLDIR)/ones 2 128 128 o.ra ;\ $(TOOLDIR)/delta 8 33 8 p.ra ;\ $(TOOLDIR)/repmat 1 16 p.ra p2.ra ;\ $(TOOLDIR)/repmat 6 4 p2.ra p3.ra ;\ $(TOOLDIR)/reshape 7 1 1 128 p3.ra p4.ra ;\ $(TOOLDIR)/reshape 96 32 1 p4.ra p5.ra ;\ $(TOOLDIR)/fmac xek2.ra p5.ra xek3.ra ;\ $(TOOLDIR)/repmat 1 256 p5.ra p6.ra ;\ $(TOOLDIR)/pics -S -RT:7:0:0.02 -i100 -e -w1. -B$(TESTS_OUT)/expon-basis.ra -pp6.ra -t t2.ra xek3.ra o.ra x2.ra ;\ $(TOOLDIR)/fmac -s 64 x2.ra $(TESTS_OUT)/expon-basis.ra xx.ra ;\ $(TOOLDIR)/transpose 5 6 xx.ra xxT.ra ;\ $(TOOLDIR)/scale 4. xxT.ra xxS.ra ;\ $(TOOLDIR)/nrmse -t 0.05 $(TESTS_OUT)/phantom-exp.ra xxS.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-pics-linsub tests/test-pics-linsub-noncart bart-0.5.00/tests/lrmatrix.mk000066400000000000000000000004721353046746100160750ustar00rootroot00000000000000 tests/test-lrmatrix: lrmatrix nrmse ones set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 10 10 o.ra ;\ $(TOOLDIR)/lrmatrix -s -o y.ra o.ra x.ra ;\ $(TOOLDIR)/nrmse -s -t 0.002 o.ra y.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-lrmatrix bart-0.5.00/tests/nlinv.mk000066400000000000000000000007511353046746100153610ustar00rootroot00000000000000 tests/test-nlinv: normalize nlinv pocsense nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/nlinv $(TESTS_OUT)/shepplogan_coil_ksp.ra r.ra c.ra ;\ $(TOOLDIR)/normalize 8 c.ra c_norm.ra ;\ $(TOOLDIR)/pocsense -i1 $(TESTS_OUT)/shepplogan_coil_ksp.ra c_norm.ra proj.ra ;\ $(TOOLDIR)/nrmse -t 0.05 proj.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-nlinv bart-0.5.00/tests/nrmse.mk000066400000000000000000000005761353046746100153640ustar00rootroot00000000000000 tests/test-nrmse-scale: nrmse scale $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_fftu.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/scale 2.i $(TESTS_OUT)/shepplogan.ra shepplogan_sc.ra ;\ $(TOOLDIR)/nrmse -s -t 0.000001 $(TESTS_OUT)/shepplogan.ra shepplogan_sc.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-nrmse-scale bart-0.5.00/tests/nufft.mk000066400000000000000000000122031353046746100153500ustar00rootroot00000000000000 # compare with FFT on a Cartesian grid tests/test-nudft-forward: traj nufft reshape nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_fft.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -x128 -y128 traj.ra ;\ $(TOOLDIR)/nufft -s traj.ra $(TESTS_OUT)/shepplogan.ra shepplogan_ksp2.ra ;\ $(TOOLDIR)/reshape 7 128 128 1 shepplogan_ksp2.ra shepplogan_ksp3.ra ;\ $(TOOLDIR)/nrmse -t 0.0001 $(TESTS_OUT)/shepplogan_fft.ra shepplogan_ksp3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # compare with FFT on a Cartesian grid tests/test-nufft-forward: traj nufft reshape nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_fftu.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -x128 -y128 traj.ra ;\ $(TOOLDIR)/nufft -P traj.ra $(TESTS_OUT)/shepplogan.ra shepplogan_ksp2.ra ;\ $(TOOLDIR)/reshape 7 128 128 1 shepplogan_ksp2.ra shepplogan_ksp3.ra ;\ $(TOOLDIR)/nrmse -t 0.0015 $(TESTS_OUT)/shepplogan_fftu.ra shepplogan_ksp3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # compare nufft and nufdt # FIXME: scaling is slightly off tests/test-nufft-nudft: traj nufft reshape nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x128 -y12 traj.ra ;\ $(TOOLDIR)/nufft -P traj.ra $(TESTS_OUT)/shepplogan.ra shepplogan_ksp1.ra ;\ $(TOOLDIR)/nufft -s traj.ra $(TESTS_OUT)/shepplogan.ra shepplogan_ksp2.ra ;\ $(TOOLDIR)/scale 128. shepplogan_ksp1.ra shepplogan_ksp3.ra ;\ $(TOOLDIR)/nrmse -s -t 0.00008 shepplogan_ksp2.ra shepplogan_ksp3.ra ;\ $(TOOLDIR)/nrmse -t 0.0015 shepplogan_ksp2.ra shepplogan_ksp3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test adjoint using definition tests/test-nudft-adjoint: zeros noise reshape traj nufft fmac nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/zeros 3 64 64 1 z.ra ;\ $(TOOLDIR)/noise -s123 z.ra n1.ra ;\ $(TOOLDIR)/noise -s321 z.ra n2b.ra ;\ $(TOOLDIR)/reshape 7 1 64 64 n2b.ra n2.ra ;\ $(TOOLDIR)/traj -r -x64 -y64 traj.ra ;\ $(TOOLDIR)/nufft -s traj.ra n1.ra k.ra ;\ $(TOOLDIR)/nufft -s -a traj.ra n2.ra x.ra ;\ $(TOOLDIR)/fmac -C -s7 n1.ra x.ra s1.ra ;\ $(TOOLDIR)/fmac -C -s7 k.ra n2.ra s2.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 s1.ra s2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test adjoint using definition tests/test-nufft-adjoint: zeros noise reshape traj nufft fmac nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/zeros 3 128 128 1 z.ra ;\ $(TOOLDIR)/noise -s123 z.ra n1.ra ;\ $(TOOLDIR)/noise -s321 z.ra n2b.ra ;\ $(TOOLDIR)/reshape 7 1 128 128 n2b.ra n2.ra ;\ $(TOOLDIR)/traj -r -x128 -y128 traj.ra ;\ $(TOOLDIR)/nufft traj.ra n1.ra k.ra ;\ $(TOOLDIR)/nufft -a traj.ra n2.ra x.ra ;\ $(TOOLDIR)/fmac -C -s7 n1.ra x.ra s1.ra ;\ $(TOOLDIR)/fmac -C -s7 k.ra n2.ra s2.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 s1.ra s2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test inverse using definition tests/test-nufft-inverse: traj scale phantom nufft nrmse set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y201 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/nufft -r -i traj2.ra ksp.ra reco.ra ;\ $(TOOLDIR)/nufft traj2.ra reco.ra k2.ra ;\ $(TOOLDIR)/nrmse -t 0.001 ksp.ra k2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test toeplitz by comparing to non-toeplitz tests/test-nufft-toeplitz: traj phantom nufft nrmse set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x128 -y128 traj.ra ;\ $(TOOLDIR)/phantom -k -t traj.ra ksp.ra ;\ $(TOOLDIR)/nufft -P -l1. -i -r traj.ra ksp.ra reco1.ra ;\ $(TOOLDIR)/nufft -P -l1. -i -t traj.ra ksp.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.0015 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test batch mode tests/test-nufft-batch: traj phantom repmat nufft nrmse set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x64 -y11 traj.ra ;\ $(TOOLDIR)/phantom -k -t traj.ra ksp.ra ;\ $(TOOLDIR)/nufft -i -r traj.ra ksp.ra reco.ra ;\ $(TOOLDIR)/repmat 3 2 ksp.ra ksp2.ra ;\ $(TOOLDIR)/nufft -i -r traj.ra ksp2.ra reco2.ra ;\ $(TOOLDIR)/repmat 3 2 reco.ra reco1.ra ;\ $(TOOLDIR)/nrmse -t 0.001 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-nufft-gpu: traj phantom nufft nrmse set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x128 -y128 traj.ra ;\ $(TOOLDIR)/phantom -k -t traj.ra ksp.ra ;\ $(TOOLDIR)/nufft -l1. -i -r traj.ra ksp.ra reco1.ra ;\ $(TOOLDIR)/nufft -l1. -g -i -t traj.ra ksp.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.002 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-nufft-forward tests/test-nufft-adjoint tests/test-nufft-inverse tests/test-nufft-toeplitz TESTS += tests/test-nufft-batch TESTS += tests/test-nufft-nudft tests/test-nudft-forward tests/test-nudft-adjoint TESTS_GPU += tests/test-nufft-gpu bart-0.5.00/tests/out/000077500000000000000000000000001353046746100145065ustar00rootroot00000000000000bart-0.5.00/tests/out/.gitignore000066400000000000000000000001071353046746100164740ustar00rootroot00000000000000# Ignore everything in this directory * # Except this file !.gitignore bart-0.5.00/tests/phantom.mk000066400000000000000000000037021353046746100157000ustar00rootroot00000000000000 $(TESTS_OUT)/shepplogan.ra: phantom $(TOOLDIR)/phantom $@ $(TESTS_OUT)/shepplogan_ksp.ra: phantom $(TOOLDIR)/phantom -k $@ $(TESTS_OUT)/shepplogan_coil.ra: phantom $(TOOLDIR)/phantom -s8 $@ $(TESTS_OUT)/shepplogan_coil_ksp.ra: phantom $(TOOLDIR)/phantom -s8 -k $@ $(TESTS_OUT)/coils.ra: phantom $(TOOLDIR)/phantom -S8 $@ tests/test-phantom-ksp: fft nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fft -i 7 $(TESTS_OUT)/shepplogan_ksp.ra shepplogan_img.ra ;\ $(TOOLDIR)/nrmse -t 0.22 $(TESTS_OUT)/shepplogan.ra shepplogan_img.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-phantom-noncart: traj phantom reshape nrmse $(TESTS_OUT)/shepplogan_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj traj.ra ;\ $(TOOLDIR)/phantom -k -t traj.ra shepplogan_ksp2.ra ;\ $(TOOLDIR)/reshape 7 128 128 1 shepplogan_ksp2.ra shepplogan_ksp3.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 $(TESTS_OUT)/shepplogan_ksp.ra shepplogan_ksp3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-phantom-coil: fmac nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/coils.ra sl_coil2.ra ;\ $(TOOLDIR)/nrmse -t 0. $(TESTS_OUT)/shepplogan_coil.ra sl_coil2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-phantom-ksp-coil: fft nrmse $(TESTS_OUT)/shepplogan_coil.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fft -i 7 $(TESTS_OUT)/shepplogan_coil_ksp.ra shepplogan_cimg.ra ;\ $(TOOLDIR)/nrmse -t 0.22 $(TESTS_OUT)/shepplogan_coil.ra shepplogan_cimg.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-phantom-ksp tests/test-phantom-noncart tests/test-phantom-coil tests/test-phantom-ksp-coil bart-0.5.00/tests/pics.mk000066400000000000000000000273721353046746100152010ustar00rootroot00000000000000 tests/test-pics-pi: pics scale nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/pics -S -r0.001 $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco.ra ;\ $(TOOLDIR)/scale 128. reco.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.23 reco2.ra $(TESTS_OUT)/shepplogan.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-noncart: traj scale phantom ones pics nufft nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y64 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -S -r0.001 -t traj2.ra ksp.ra o.ra reco.ra ;\ $(TOOLDIR)/nufft traj2.ra reco.ra k2.ra ;\ $(TOOLDIR)/nrmse -t 0.002 ksp.ra k2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-cs: traj scale phantom ones pics nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y48 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -S -RT:7:0:0.001 -u0.1 -e -t traj2.ra ksp.ra o.ra reco.ra ;\ $(TOOLDIR)/scale 128. reco.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.22 reco2.ra $(TESTS_OUT)/shepplogan.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-wavl1: traj scale phantom ones pics nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y48 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -S -RW:3:0:0.001 -i150 -e -t traj2.ra ksp.ra o.ra reco.ra ;\ $(TOOLDIR)/scale 128. reco.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.23 reco2.ra $(TESTS_OUT)/shepplogan.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-poisson-wavl1: poisson squeeze fft fmac ones pics nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/poisson -Y128 -Z128 -y1.2 -z1.2 -e -v -C24 p.ra ;\ $(TOOLDIR)/squeeze p.ra p2.ra ;\ $(TOOLDIR)/fft -u 7 $(TESTS_OUT)/shepplogan.ra ksp1.ra ;\ $(TOOLDIR)/fmac ksp1.ra p2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -S -RW:3:0:0.01 -i50 ksp.ra o.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0.21 $(TESTS_OUT)/shepplogan.ra reco.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-bpwavl1: scale fft noise fmac ones pics nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/scale 50 $(TESTS_OUT)/shepplogan.ra shepp.ra ;\ $(TOOLDIR)/fft -u 7 shepp.ra ksp1.ra ;\ $(TOOLDIR)/noise -s 1 -n 1 ksp1.ra ksp2.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -a -P 128 -w1. -RW:3:0:1. -i50 ksp2.ra o.ra reco.ra ;\ $(TOOLDIR)/pics -m -P 128 -w1. -RW:3:0:1. -i50 -u 2 ksp2.ra o.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.08 shepp.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0.08 shepp.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-bp-noncart: traj scale phantom pics nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y64 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -e -S -RW:3:0:0.0001 -t traj2.ra ksp.ra o.ra reco1.ra ;\ $(TOOLDIR)/pics -e -a -P0.1 -S -RW:3:0:0.0001 -t traj2.ra ksp.ra o.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.09 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-joint-wavl1: poisson reshape fft fmac ones pics slice nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/poisson -Y128 -Z128 -y1.1 -z1.1 -e -v -C24 -T2 p.ra ;\ $(TOOLDIR)/reshape 63 128 128 1 1 1 2 p.ra p2.ra ;\ $(TOOLDIR)/fft -u 7 $(TESTS_OUT)/shepplogan.ra ksp1.ra ;\ $(TOOLDIR)/fmac ksp1.ra p2.ra ksp.ra ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -S -RW:3:32:0.02 -i50 ksp.ra o.ra reco2.ra ;\ $(TOOLDIR)/slice 5 0 reco2.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0.22 $(TESTS_OUT)/shepplogan.ra reco.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-pics: traj scale phantom pics nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y32 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -s8 -t traj2.ra ksp.ra ;\ $(TOOLDIR)/pics -S -RT:7:0:0.001 -u1000000000. -e -t traj2.ra ksp.ra $(TESTS_OUT)/coils.ra reco.ra ;\ $(TOOLDIR)/scale 128. reco.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.22 reco2.ra $(TESTS_OUT)/shepplogan.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test that weights =0.5 have no effect tests/test-pics-weights: pics ones nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 128 128 weights.ra ;\ $(TOOLDIR)/scale 0.5 weights.ra weights2.ra ;\ $(TOOLDIR)/pics -S -r0.001 $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco1.ra ;\ $(TOOLDIR)/pics -S -r0.001 -p weights2.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 reco2.ra reco1.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ # test that weights =0.5 have no effect # FIXME: this was 0.005 before but fails on travis tests/test-pics-noncart-weights: traj scale ones phantom pics nrmse $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -y32 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -s8 -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 4 1 256 32 1 weights.ra ;\ $(TOOLDIR)/scale 0.5 weights.ra weights2.ra ;\ $(TOOLDIR)/pics -S -r0.001 -p weights2.ra -t traj2.ra ksp.ra $(TESTS_OUT)/coils.ra reco1.ra ;\ $(TOOLDIR)/pics -S -r0.001 -t traj2.ra ksp.ra $(TESTS_OUT)/coils.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.010 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-warmstart: pics scale nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 128 128 1 o.ra ;\ $(TOOLDIR)/pics -i0 -Wo.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0. o.ra reco.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-batch: pics repmat nrmse $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/repmat 5 32 $(TESTS_OUT)/shepplogan_coil_ksp.ra kspaces.ra ;\ $(TOOLDIR)/pics -r0.01 -L32 kspaces.ra $(TESTS_OUT)/coils.ra reco1.ra ;\ $(TOOLDIR)/pics -r0.01 kspaces.ra $(TESTS_OUT)/coils.ra reco2.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 reco1.ra reco2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-tedim: phantom fmac fft pics nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/phantom -s4 -m coils.ra ;\ $(TOOLDIR)/phantom -m img.ra ;\ $(TOOLDIR)/fmac img.ra coils.ra cimg.ra ;\ $(TOOLDIR)/fft -u 7 cimg.ra ksp.ra ;\ $(TOOLDIR)/pics -i10 -w 1. -m ksp.ra coils.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0.01 img.ra reco.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-basis: ones delta fmac pics nrmse repmat scale slice $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/pics -S $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra gold.ra ;\ $(TOOLDIR)/delta 16 33 128 p.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan_coil_ksp.ra p.ra pk.ra ;\ $(TOOLDIR)/ones 6 1 1 1 1 1 128 o.ra ;\ $(TOOLDIR)/repmat 6 2 o.ra o2.ra ;\ $(TOOLDIR)/pics -S -Bo2.ra pk.ra $(TESTS_OUT)/coils.ra reco.ra ;\ $(TOOLDIR)/scale 2. reco.ra reco2.ra ;\ $(TOOLDIR)/slice 6 0 reco2.ra reco20.ra ;\ $(TOOLDIR)/nrmse -t 0.00001 gold.ra reco20.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-basis-noncart: traj scale phantom delta fmac ones repmat pics slice nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -D -y31 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/delta 16 36 31 p.ra ;\ $(TOOLDIR)/fmac ksp.ra p.ra pk.ra ;\ $(TOOLDIR)/repmat 1 256 p.ra p2.ra ;\ $(TOOLDIR)/ones 6 1 1 1 1 1 31 o.ra ;\ $(TOOLDIR)/repmat 6 2 o.ra o2.ra ;\ $(TOOLDIR)/ones 3 128 128 1 coils.ra ;\ $(TOOLDIR)/pics -r0.001 -t traj2.ra -pp2.ra -Bo2.ra pk.ra coils.ra reco1.ra ;\ $(TOOLDIR)/pics -r0.001 -t traj2.ra ksp.ra coils.ra reco.ra ;\ $(TOOLDIR)/scale 4. reco1.ra reco2.ra ;\ $(TOOLDIR)/slice 6 0 reco2.ra reco20.ra ;\ $(TOOLDIR)/nrmse -t 0.002 reco.ra reco20.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-basis-noncart-memory: traj scale phantom ones join transpose pics slice nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -D -y31 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/ones 6 1 1 1 1 1 31 o.ra ;\ $(TOOLDIR)/scale 1. o.ra o1.ra ;\ $(TOOLDIR)/join 6 o.ra o1.ra o2.ra ;\ $(TOOLDIR)/ones 3 128 128 1 coils.ra ;\ $(TOOLDIR)/transpose 2 5 traj2.ra traj3.ra ;\ $(TOOLDIR)/transpose 2 5 ksp.ra ksp1.ra ;\ $(TOOLDIR)/pics -r0.001 -t traj3.ra -Bo2.ra ksp1.ra coils.ra reco1.ra ;\ $(TOOLDIR)/pics -r0.001 -t traj2.ra ksp.ra coils.ra reco.ra ;\ $(TOOLDIR)/scale 4. reco1.ra reco2.ra ;\ $(TOOLDIR)/slice 6 0 reco2.ra reco20.ra ;\ $(TOOLDIR)/nrmse -t 0.002 reco.ra reco20.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-pics-basis-noncart-memory2: traj scale phantom ones join noise transpose fmac pics slice nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -r -x256 -D -y301 traj.ra ;\ $(TOOLDIR)/scale 0.5 traj.ra traj2.ra ;\ $(TOOLDIR)/phantom -t traj2.ra ksp.ra ;\ $(TOOLDIR)/phantom p.ra ;\ $(TOOLDIR)/scale 0.5 ksp.ra ksp2.ra ;\ $(TOOLDIR)/zeros 7 1 1 1 1 1 301 2 o.ra ;\ $(TOOLDIR)/noise o.ra o1.ra ;\ $(TOOLDIR)/join 6 ksp.ra ksp2.ra ksp3.ra ;\ $(TOOLDIR)/transpose 2 5 ksp3.ra ksp4.ra ;\ $(TOOLDIR)/fmac -s 64 ksp4.ra o1.ra ksp5.ra ;\ $(TOOLDIR)/ones 3 128 128 1 coils.ra ;\ $(TOOLDIR)/transpose 2 5 traj2.ra traj3.ra ;\ $(TOOLDIR)/pics -S -U -i100 -r0. -t traj3.ra -Bo1.ra ksp5.ra coils.ra reco1.ra ;\ $(TOOLDIR)/slice 6 0 reco1.ra reco.ra ;\ $(TOOLDIR)/slice 6 1 reco1.ra reco2.ra ;\ $(TOOLDIR)/scale 2. reco2.ra reco3.ra ;\ $(TOOLDIR)/nrmse -s -t 0.25 reco.ra p.ra ;\ $(TOOLDIR)/nrmse -s -t 0.25 reco3.ra p.ra ;\ $(TOOLDIR)/nrmse -t 0.06 reco.ra reco3.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-pics-pi tests/test-pics-noncart tests/test-pics-cs tests/test-pics-pics TESTS += tests/test-pics-wavl1 tests/test-pics-poisson-wavl1 tests/test-pics-joint-wavl1 tests/test-pics-bpwavl1 TESTS += tests/test-pics-weights tests/test-pics-noncart-weights TESTS += tests/test-pics-warmstart tests/test-pics-batch TESTS += tests/test-pics-tedim tests/test-pics-bp-noncart TESTS += tests/test-pics-basis tests/test-pics-basis-noncart tests/test-pics-basis-noncart-memory TESTS += tests/test-pics-basis-noncart-memory2 bart-0.5.00/tests/poly.mk000066400000000000000000000004571353046746100152210ustar00rootroot00000000000000tests/test-poly: ones poly nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 128 ones.ra ;\ $(TOOLDIR)/poly 128 0 1 poly.ra ;\ $(TOOLDIR)/nrmse -t 0. ones.ra poly.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-poly bart-0.5.00/tests/pyBART.cmake000066400000000000000000000027531353046746100160110ustar00rootroot00000000000000# Copyright 2018. Damien Nguyen # All rights reserved. Use of this source code is governed by # a BSD-style license which can be found in the LICENSE file. # \author Damien Nguyen add_new_test_group(pyBART) if(WIN32) add_env_var_to_group(pyBART PYTHONPATH "${PROJECT_BINARY_DIR};$ENV{PYTHONPATH}") else() add_env_var_to_group(pyBART PYTHONPATH "${PROJECT_BINARY_DIR}:$ENV{PYTHONPATH}") endif() macro(pyBART_add_test_to_group group test_name) list(APPEND _test_list_${group} ${test_name}) set(_cmd_list) foreach(_cmd ${ARGN}) set(_cmd_list "${_cmd_list}${_cmd}\n") endforeach() file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.py CONTENT "${_cmd_list}") set(TEST_${group}_${test_name} "${Python_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/pyBART_run_test.py ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.py") endmacro() pyBART_add_test_to_group(pyBART "test_pyBART_import" "import pyBART" ) pyBART_add_test_to_group(pyBART "test_pyBART_automatic_conversion" "import pyBART" "import numpy as np" "a = np.array([['0','1','2'],['3','4','5']])" "pyBART.register_memory('test.mem', a)" ) pyBART_add_test_to_group(pyBART "test_pyBART_simple" "import pyBART" "import numpy as np" "a = np.array([ [0,1,2], [3,4,5] ])" "pyBART.register_memory('test.mem', a)" "pyBART.bart('fmac test.mem test.mem test2.mem')" "b = pyBART.load_cfl('test2.mem')" "print(np.squeeze(b))" "pyBART.cleanup_memory()" ) bart-0.5.00/tests/pyBART_run_test.py000066400000000000000000000004721353046746100173000ustar00rootroot00000000000000import sys import traceback import os try: with open(sys.argv[1], 'r') as fd: for line in fd.readlines(): exec(line) except: exc_info = sys.exc_info() traceback.print_exception(*exc_info) print('Exception occurred while executing line: ', line) sys.exit(1) bart-0.5.00/tests/pythoncfl.mk000066400000000000000000000007641353046746100162450ustar00rootroot00000000000000 # test python reacfl and writecfl interface tests/test-python-cfl: $(TOOLDIR)/tests/pythoncfl.py nrmse flip $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/flip 0 $(TESTS_OUT)/shepplogan.ra shepplogan ;\ PYTHONPATH=$(TOOLDIR)/python $(TOOLDIR)/tests/pythoncfl.py shepplogan shepplogan2 ;\ $(TOOLDIR)/nrmse -t 0.000001 shepplogan shepplogan2 ;\ rm *.cfl *.hdr ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS_PYTHON += tests/test-python-cfl bart-0.5.00/tests/pythoncfl.py000077500000000000000000000010121353046746100162540ustar00rootroot00000000000000#!/usr/bin/env python from __future__ import print_function import cfl import sys # from http://stackoverflow.com/questions/5574702/how-to-print-to-stderr-in-python def errprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) def main(out_name, in_name): input = cfl.readcfl(in_name) #cfl.writecfl(input, out_name) cfl.writecfl(out_name, input) return 0 if __name__ == '__main__': if len(sys.argv) != 3: errprint('Usage:', sys.argv[0], ' ') exit(main(sys.argv[2], sys.argv[1])) bart-0.5.00/tests/slice.mk000066400000000000000000000014061353046746100153300ustar00rootroot00000000000000 tests/test-slice: ones slice resize nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 2 1 1 o.ra ;\ $(TOOLDIR)/resize -c 0 100 1 100 o.ra o0.ra ;\ $(TOOLDIR)/slice 1 50 o0.ra o1.ra ;\ $(TOOLDIR)/slice 0 50 o1.ra o2.ra ;\ $(TOOLDIR)/nrmse -t 0. o2.ra o.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-slice-multidim: ones slice resize nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 1 1 1 o.ra ;\ $(TOOLDIR)/resize -c 0 100 1 100 2 100 o.ra o0.ra ;\ $(TOOLDIR)/slice 0 50 1 50 2 50 o0.ra o1.ra ;\ $(TOOLDIR)/nrmse -t 0. o1.ra o.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-slice tests/test-slice-multidim bart-0.5.00/tests/smallfov.mk000066400000000000000000000037511353046746100160610ustar00rootroot00000000000000 # create data with small FOV problem $(TESTS_OUT)/shepplogan-smallfov-ksp.ra: traj scale phantom set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/traj -x128 -y128 t.ra ;\ $(TOOLDIR)/scale 1.5 t.ra t2.ra ;\ $(TOOLDIR)/phantom -s8 -k -t t2.ra $@ ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) $(TESTS_OUT)/cart-pattern.ra: ones resize repmat reshape extract ones join set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 3 1 1 1 o.ra ;\ $(TOOLDIR)/resize 2 2 o.ra o2.ra ;\ $(TOOLDIR)/repmat 3 64 o2.ra o3.ra ;\ $(TOOLDIR)/reshape 12 128 1 o3.ra o4.ra ;\ $(TOOLDIR)/extract 2 0 52 o4.ra o5.ra ;\ $(TOOLDIR)/ones 3 1 1 24 oc.ra ;\ $(TOOLDIR)/join 2 o5.ra oc.ra o5.ra $@ ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) tests/test-smallfov-pics: fmac fft nrmse ecalib pics $(TESTS_OUT)/shepplogan-smallfov-ksp.ra $(TESTS_OUT)/cart-pattern.ra set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan-smallfov-ksp.ra $(TESTS_OUT)/cart-pattern.ra ku.ra ;\ $(TOOLDIR)/ecalib ku.ra se.ra ;\ $(TOOLDIR)/pics -i100 ku.ra se.ra xu.ra ;\ $(TOOLDIR)/fmac -s16 xu.ra se.ra xsp.ra ;\ $(TOOLDIR)/fft -u 7 xsp.ra xsp2.ra ;\ $(TOOLDIR)/nrmse -s -t 0.035 $(TESTS_OUT)/shepplogan-smallfov-ksp.ra xsp2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-smallfov-enlive: fmac fft nrmse nlinv $(TESTS_OUT)/shepplogan-smallfov-ksp.ra $(TESTS_OUT)/cart-pattern.ra set -e ; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan-smallfov-ksp.ra $(TESTS_OUT)/cart-pattern.ra ku.ra ;\ $(TOOLDIR)/nlinv -m2 -i12 -U -S -N ku.ra xu2.ra sn.ra ;\ $(TOOLDIR)/fmac -s16 xu2.ra sn.ra xsn.ra ;\ $(TOOLDIR)/fft -u 7 xsn.ra xsn2.ra ;\ $(TOOLDIR)/nrmse -s -t 0.035 $(TESTS_OUT)/shepplogan-smallfov-ksp.ra xsn2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-smallfov-pics tests/test-smallfov-enlive bart-0.5.00/tests/squeeze.mk000066400000000000000000000006531353046746100157150ustar00rootroot00000000000000 tests/test-squeeze: ones squeeze noise nrmse set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 6 1 2 1 3 1 4 a0.ra ;\ $(TOOLDIR)/ones 3 2 3 4 b0.ra ;\ $(TOOLDIR)/noise a0.ra a1.ra ;\ $(TOOLDIR)/noise b0.ra b1.ra ;\ $(TOOLDIR)/squeeze a1.ra a2.ra ;\ $(TOOLDIR)/nrmse -t 0. b1.ra a2.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-squeeze bart-0.5.00/tests/tmp/000077500000000000000000000000001353046746100144775ustar00rootroot00000000000000bart-0.5.00/tests/tmp/.gitignore000066400000000000000000000001071353046746100164650ustar00rootroot00000000000000# Ignore everything in this directory * # Except this file !.gitignore bart-0.5.00/tests/wave.mk000066400000000000000000000015431353046746100151750ustar00rootroot00000000000000tests/test-wave: wave wavepsf scale nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/wavepsf -x 640 -y 128 wave_psf.ra ;\ $(TOOLDIR)/fft -iu 7 $(TESTS_OUT)/shepplogan_coil_ksp.ra img.ra ;\ $(TOOLDIR)/resize -c 0 640 img.ra wave_zpad.ra ;\ $(TOOLDIR)/fft -u 1 wave_zpad.ra wave_hyb.ra ;\ $(TOOLDIR)/fmac wave_hyb.ra wave_psf.ra wave_acq.ra ;\ $(TOOLDIR)/fft -u 6 wave_acq.ra wave_ksp.ra ;\ $(TOOLDIR)/wave $(TESTS_OUT)/coils.ra wave_psf.ra wave_ksp.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0.23 -s reco.ra $(TESTS_OUT)/shepplogan.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-wave bart-0.5.00/tests/wavelet.mk000066400000000000000000000071531353046746100157050ustar00rootroot00000000000000 tests/test-wavelet: wavelet nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/wavelet 3 $(TESTS_OUT)/shepplogan.ra w.ra ;\ $(TOOLDIR)/wavelet -a 3 128 128 w.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 $(TESTS_OUT)/shepplogan.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-wavelet-batch: ones resize circshift fft fmac wavelet nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 1 one.ra ;\ $(TOOLDIR)/resize -c 2 100 one.ra one2.ra ;\ $(TOOLDIR)/circshift 2 1 one2.ra one3.ra ;\ $(TOOLDIR)/fft 4 one3.ra ph.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan.ra ph.ra ph2.ra ;\ $(TOOLDIR)/wavelet 3 ph2.ra w.ra ;\ $(TOOLDIR)/wavelet -a 3 128 128 w.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 ph2.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-wavelet-batch1: ones resize circshift fft fmac wavelet slice nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 1 one.ra ;\ $(TOOLDIR)/resize -c 2 100 one.ra one2.ra ;\ $(TOOLDIR)/circshift 2 1 one2.ra one3.ra ;\ $(TOOLDIR)/fft 4 one3.ra ph.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan.ra ph.ra ph2.ra ;\ $(TOOLDIR)/wavelet 3 ph2.ra w.ra ;\ $(TOOLDIR)/slice 2 80 w.ra w1.ra ;\ $(TOOLDIR)/slice 2 80 ph2.ra ph1.ra ;\ $(TOOLDIR)/wavelet 3 ph1.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 w1.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-wavelet-batch2: ones resize circshift fft fmac transpose wavelet nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 1 one.ra ;\ $(TOOLDIR)/resize -c 2 100 one.ra one2.ra ;\ $(TOOLDIR)/circshift 2 1 one2.ra one3.ra ;\ $(TOOLDIR)/fft 4 one3.ra ph.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan.ra ph.ra ph2.ra ;\ $(TOOLDIR)/transpose 0 2 ph2.ra ph3.ra ;\ $(TOOLDIR)/wavelet 6 ph3.ra w.ra ;\ $(TOOLDIR)/wavelet -a 6 128 128 w.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 ph3.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-wavelet-batch3: ones resize circshift fft fmac transpose wavelet nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 1 one.ra ;\ $(TOOLDIR)/resize -c 2 100 one.ra one2.ra ;\ $(TOOLDIR)/circshift 2 1 one2.ra one3.ra ;\ $(TOOLDIR)/fft 4 one3.ra ph.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan.ra ph.ra ph2.ra ;\ $(TOOLDIR)/transpose 1 2 ph2.ra ph3.ra ;\ $(TOOLDIR)/wavelet 5 ph3.ra w.ra ;\ $(TOOLDIR)/wavelet -a 5 128 128 w.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 ph3.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ tests/test-wavelet-batch4: ones resize circshift fft fmac transpose wavelet nrmse $(TESTS_OUT)/shepplogan.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/ones 1 1 one.ra ;\ $(TOOLDIR)/resize -c 2 5 3 5 4 5 one.ra one2.ra ;\ $(TOOLDIR)/circshift 2 1 one2.ra one3.ra ;\ $(TOOLDIR)/fft 28 one3.ra ph.ra ;\ $(TOOLDIR)/fmac $(TESTS_OUT)/shepplogan.ra ph.ra ph2.ra ;\ $(TOOLDIR)/transpose 0 3 ph2.ra ph3.ra ;\ $(TOOLDIR)/wavelet 10 ph3.ra w.ra ;\ $(TOOLDIR)/wavelet -a 10 128 128 w.ra a.ra ;\ $(TOOLDIR)/nrmse -t 0.000001 ph3.ra a.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-wavelet tests/test-wavelet-batch tests/test-wavelet-batch1 TESTS += tests/test-wavelet-batch2 tests/test-wavelet-batch3 tests/test-wavelet-batch4 bart-0.5.00/tests/whiten.mk000066400000000000000000000014621353046746100155310ustar00rootroot00000000000000 tests/test-whiten: zeros ones noise join whiten std nrmse show set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/zeros 1 4096 z.ra ;\ $(TOOLDIR)/noise -s 1 -n 1 z.ra n1.ra ;\ $(TOOLDIR)/noise -s 2 -n 2 z.ra n2.ra ;\ $(TOOLDIR)/noise -s 3 -n 3 z.ra n3.ra ;\ $(TOOLDIR)/join 3 n1.ra n2.ra n3.ra n.ra ;\ $(TOOLDIR)/ones 1 4096 o.ra ;\ $(TOOLDIR)/noise -s 1 -n 1 o.ra s1.ra ;\ $(TOOLDIR)/noise -s 2 -n 2 o.ra s2.ra ;\ $(TOOLDIR)/noise -s 3 -n 3 o.ra s3.ra ;\ $(TOOLDIR)/join 3 s1.ra s2.ra s3.ra s.ra ;\ $(TOOLDIR)/whiten s.ra n.ra w.ra ;\ $(TOOLDIR)/std 7 w.ra d.ra ;\ $(TOOLDIR)/ones 4 1 1 1 3 o.ra ;\ $(TOOLDIR)/nrmse -t 0.001 d.ra o.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-whiten bart-0.5.00/tests/wshfl.mk000066400000000000000000000026511353046746100153570ustar00rootroot00000000000000tests/test-wshfl: wavepsf fmac fft resize transpose squeeze poly join wshfl nrmse $(TESTS_OUT)/shepplogan.ra $(TESTS_OUT)/shepplogan_coil_ksp.ra $(TESTS_OUT)/coils.ra set -e; mkdir $(TESTS_TMP) ; cd $(TESTS_TMP) ;\ $(TOOLDIR)/wavepsf -x 640 -y 128 wave_psf.ra ;\ $(TOOLDIR)/fft -iu 7 $(TESTS_OUT)/shepplogan_coil_ksp.ra img.ra ;\ $(TOOLDIR)/resize -c 0 640 img.ra wave_zpad.ra ;\ $(TOOLDIR)/fft -u 1 wave_zpad.ra wave_hyb.ra ;\ $(TOOLDIR)/fmac wave_hyb.ra wave_psf.ra wave_acq.ra ;\ $(TOOLDIR)/fft -u 6 wave_acq.ra wave_ksp.ra ;\ $(TOOLDIR)/transpose 1 3 wave_ksp.ra permuted.ra ;\ $(TOOLDIR)/squeeze permuted.ra table.ra ;\ $(TOOLDIR)/poly 128 1 0 1 ky.ra ;\ $(TOOLDIR)/poly 128 1 0 0 kz.ra ;\ $(TOOLDIR)/poly 128 1 0 0 te.ra ;\ $(TOOLDIR)/join 1 ky.ra kz.ra te.ra reorder.ra ;\ $(TOOLDIR)/poly 1 0 1 phi.ra ;\ $(TOOLDIR)/wshfl -i 100 $(TESTS_OUT)/coils.ra wave_psf.ra phi.ra reorder.ra table.ra reco.ra ;\ $(TOOLDIR)/nrmse -t 0.23 -s $(TESTS_OUT)/shepplogan.ra reco.ra ;\ rm *.ra ; cd .. ; rmdir $(TESTS_TMP) touch $@ TESTS += tests/test-wshfl bart-0.5.00/utests/000077500000000000000000000000001353046746100140645ustar00rootroot00000000000000bart-0.5.00/utests/test_batchsvd.c000066400000000000000000000025761353046746100170770ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include "lowrank/batchsvd.h" #include "num/flpmath.h" #include "misc/debug.h" #include "misc/misc.h" #include "utest.h" static bool test_batch_svthresh_tall(void) { complex float inout[1][5][3] = { { { 3., 0., 0. }, { 0., 2., 0. }, { 0., 0., 1. }, { 0., 0., 0. }, { 0., 0., 0. }, } }; batch_svthresh(3, 5, 1, 1., inout); const complex float ref[1][5][3] = { { { 2., 0., 0. }, { 0., 1., 0. }, { 0., 0., 0. }, { 0., 0., 0. }, { 0., 0., 0. }, } }; long dims[3] = { 3, 5, 1 }; UT_ASSERT(md_znrmse(3, dims, &ref[0][0][0], &inout[0][0][0]) < UT_TOL); return true; } static bool test_batch_svthresh_wide(void) { complex float inout[1][3][5] = { { { 3., 0., 0., 0., 0. }, { 0., 2., 0., 0., 0. }, { 0., 0., 1., 0., 0. }, } }; batch_svthresh(5, 3, 1, 1., inout); const complex float ref[1][3][5] = { { { 2., 0., 0., 0., 0. }, { 0., 1., 0., 0., 0. }, { 0., 0., 0., 0., 0. }, } }; long dims[3] = { 5, 3, 1 }; UT_ASSERT(md_znrmse(3, dims, &ref[0][0][0], &inout[0][0][0]) < UT_TOL); return true; } UT_REGISTER_TEST(test_batch_svthresh_tall); UT_REGISTER_TEST(test_batch_svthresh_wide); bart-0.5.00/utests/test_biot_savart.c000066400000000000000000000020741353046746100176070ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include #include #include "num/vec3.h" #include "simu/biot_savart.h" #include "utest.h" static bool test_vec3_ring(void) { unsigned int N = 10; vec3_t r[N]; vec3_t c = { 0., 0., 0. }; vec3_t n = { 1., 0., 0. }; vec3_ring(N, r, c, n, 0.33); bool ok = true; for (unsigned int i = 0; i < N; i++) ok &= (1.E-6 > fabs(0.33 - vec3_norm(r[i]))); for (unsigned int i = 0; i < N; i++) ok &= (0. == vec3_sdot(r[i], n)); return ok; } static bool test_biot_savart(void) { unsigned int N = 100; vec3_t r[N]; vec3_t c = { 0.6, 0.3, 0.1 }; vec3_t n = { 1., 0., 0. }; vec3_ring(N, r, c, n, 0.5); vec3_t x; biot_savart(x, c, N, (const vec3_t*)r); vec3_t d; vec3_sub(d, x, n); return (1.E-3 > vec3_norm(d)); } UT_REGISTER_TEST(test_vec3_ring); UT_REGISTER_TEST(test_biot_savart); bart-0.5.00/utests/test_blas.c000066400000000000000000000035661353046746100162220ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/blas.h" #include "num/rand.h" #include "misc/misc.h" #include "misc/debug.h" #include "utest.h" static void matrix_mult(int A, int B, int C, complex float (*dst)[A][C], const complex float (*src1)[A][B], const complex float (*src2)[B][C]) { for (int i = 0; i < A; i++) { for (int k = 0; k < C; k++) { (*dst)[i][k] = 0.; for (int j = 0; j < B; j++) (*dst)[i][k] += (*src1)[i][j] * (*src2)[j][k]; } } } static bool test_blas_matrix_mult(void) { int A = 10; int B = 20; int C = 30; long odims[3] = { A, 1, C }; long idims1[3] = { 1, B, C }; long idims2[3] = { A, B, 1 }; complex float* dst1 = md_alloc(3, odims, CFL_SIZE); complex float* dst2 = md_alloc(3, odims, CFL_SIZE); complex float* src1 = md_alloc(3, idims1, CFL_SIZE); complex float* src2 = md_alloc(3, idims2, CFL_SIZE); md_gaussian_rand(3, odims, dst1); md_gaussian_rand(3, odims, dst2); md_gaussian_rand(3, idims1, src1); md_gaussian_rand(3, idims2, src2); blas_matrix_multiply(A, C, B, MD_CAST_ARRAY2(complex float, 3, odims, dst1, 0, 2), MD_CAST_ARRAY2(const complex float, 3, idims2, src2, 0, 1), MD_CAST_ARRAY2(const complex float, 3, idims1, src1, 1, 2)); // (A^T B^T)^T = B A matrix_mult(C, B, A, &MD_CAST_ARRAY2(complex float, 3, odims, dst2, 0, 2), &MD_CAST_ARRAY2(const complex float, 3, idims1, src1, 1, 2), &MD_CAST_ARRAY2(const complex float, 3, idims2, src2, 0, 1)); double err = md_znrmse(3, odims, dst2, dst1); md_free(src1); md_free(src2); md_free(dst1); md_free(dst2); return (err < UT_TOL); } UT_REGISTER_TEST(test_blas_matrix_mult); bart-0.5.00/utests/test_flpmath.c000066400000000000000000000140531353046746100167250ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jonathan Tamir * 2016-2019 Martin Uecker */ #include #include "num/flpmath.h" #include "num/multind.h" #include "num/rand.h" #include "misc/misc.h" #include "misc/debug.h" #include "utest.h" // include test data #include "test_flpmath_data.h" static bool test_md_zfmacc2_flags(unsigned int D, const long idims[D], unsigned int flags, const complex float* in1, const complex float* in2, const complex float* out_ref) { long odims[D]; md_select_dims(D, ~flags, odims, idims); complex float* out = md_calloc(D, odims, CFL_SIZE); long istr[D]; long ostr[D]; md_calc_strides(D, istr, idims, CFL_SIZE); md_calc_strides(D, ostr, odims, CFL_SIZE); md_zfmacc2(D, idims, ostr, out, istr, in1, istr, in2); float err = md_znrmse(D, odims, out_ref, out); md_free(out); UT_ASSERT(err < UT_TOL); return true; } /* * Tests based on previously generated data included in the header file */ static bool test_md_zfmacc2(void) { long idims[4] = { 3, 3, 3, 3 }; bool ret = true; for (unsigned int flags = 0u; flags < 16u; flags++) { debug_printf(DP_DEBUG1, "Testing md_zfmacc2_flags with flags=%d\n", flags); ret &= test_md_zfmacc2_flags(4, idims, flags, test_md_in0, test_md_in1, test_md_zfmacc2_out[flags]); } return ret; } static bool test_md_zavg_flags(unsigned int D, const long idims[D], unsigned int flags, const complex float* in, const complex float* out_ref, bool wavg) { long odims[D]; md_select_dims(D, ~flags, odims, idims); complex float* out = md_alloc(D, odims, CFL_SIZE); (wavg ? md_zwavg : md_zavg)(D, idims, flags, out, in); float err = md_znrmse(D, odims, out_ref, out); md_free(out); UT_ASSERT(err < UT_TOL); return true; } /* * Tests based on previously generated data included in the header file */ static bool test_md_zwavg(void) { long idims[4] = { 3, 3, 3, 3 }; bool wavg = true; bool ret = true; for (unsigned int flags = 0u; flags < 16u; flags++) { debug_printf(DP_DEBUG1, "Testing md_zwavg_flags with flags=%d\n", flags); ret &= test_md_zavg_flags(4, idims, flags, test_md_in0, test_md_zwavg_out[flags], wavg); } return ret; } static bool test_md_zavg(void) { long idims[4] = { 3, 3, 3, 3 }; bool wavg = false; bool ret = true; for (unsigned int flags = 0u; flags < 16u; flags++) { debug_printf(DP_DEBUG1, "Testing md_zavg_flags with flags=%d\n", flags); ret &= test_md_zavg_flags(4, idims, flags, test_md_in0, test_md_zavg_out[flags], wavg); } return ret; } static void matrix_mult(int A, int B, int C, complex float (*dst)[A][C], const complex float (*src1)[A][B], const complex float (*src2)[B][C]) { for (int i = 0; i < A; i++) { for (int k = 0; k < C; k++) { (*dst)[i][k] = 0.; for (int j = 0; j < B; j++) (*dst)[i][k] += (*src1)[i][j] * (*src2)[j][k]; } } } static bool test_md_zmatmul(void) { int A = 10; int B = 20; int C = 30; long odims[3] = { C, 1, A }; long idims1[3] = { 1, B, A }; long idims2[3] = { C, B, 1 }; complex float* dst1 = md_alloc(3, odims, CFL_SIZE); complex float* dst2 = md_alloc(3, odims, CFL_SIZE); complex float* src1 = md_alloc(3, idims1, CFL_SIZE); complex float* src2 = md_alloc(3, idims2, CFL_SIZE); md_gaussian_rand(3, odims, dst1); md_gaussian_rand(3, odims, dst2); md_gaussian_rand(3, idims1, src1); md_gaussian_rand(3, idims2, src2); md_zmatmul(3, odims, dst1, idims1, src1, idims2, src2); matrix_mult(A, B, C, &MD_CAST_ARRAY2(complex float, 3, odims, dst2, 0, 2), &MD_CAST_ARRAY2(const complex float, 3, idims1, src1, 1, 2), &MD_CAST_ARRAY2(const complex float, 3, idims2, src2, 0, 1)); double err = md_znrmse(3, odims, dst2, dst1); md_free(src1); md_free(src2); md_free(dst1); md_free(dst2); return (err < UT_TOL); } static bool test_md_zhardthresh(void) { complex float test_vec[] = { 1., 2., 3., 4., 5., 6., 7., 8., 9. }; unsigned int N = ARRAY_SIZE(test_vec); complex float test_out[N]; unsigned int k = 5; md_zhardthresh(1, (long[1]){ N }, k, 0, test_out, test_vec); bool ok = true; for (unsigned int i = 0; i < N - k; i++) ok &= (0. == test_out[i]); for (unsigned int i = N - k; i < N; i++) ok &= (test_vec[i] == test_out[i]); return ok; } static bool test_md_zvar(void) { const complex float test_vec[] = { 1 -6.j, 2 - 5.j, 3 - 4.j, 4 - 3.j, 5 - 2.j, 6 - 1.j }; const complex float ref[] = { 8., 8. }; long idims[2] = { 2, 3 }; long odims[2] = { 2, 1 }; complex float* out = md_alloc(2, odims, CFL_SIZE); md_zvar(2, idims, MD_BIT(1), out, test_vec); double err = md_znrmse(2, odims, ref, out); md_free(out); return (err < UT_TOL); } static bool test_md_zstd(void) { const complex float test_vec[] = { 1 -6.j, 2 - 5.j, 3 - 4.j, 4 - 3.j, 5 - 2.j, 6 - 1.j }; const complex float ref[] = { 1., 1., 1.}; long idims[2] = { 2, 3 }; long odims[2] = { 1, 3 }; complex float* out = md_alloc(2, odims, CFL_SIZE); md_zstd(2, idims, MD_BIT(0), out, test_vec); double err = md_znrmse(2, odims, ref, out); md_free(out); return (err < UT_TOL); } static bool test_md_zconv(void) { enum { N = 1 }; long idims[N] = { 10 }; long kdims[N] = { 3 }; long odims[N] = { 8 }; complex float* x = md_calloc(N, idims, sizeof(complex float)); complex float* y = md_calloc(N, odims, sizeof(complex float)); complex float* z = md_calloc(N, odims, sizeof(complex float)); x[5] = 1.; z[3] = 0.5; z[4] = 1.; z[5] = -0.5; complex float k[3] = { 0.5, 1., -0.5 }; md_zconv(N, 1u, odims, y, kdims, &k[0], idims, x); float err = md_znrmse(N, odims, y, z); md_free(x); md_free(y); md_free(z); return (err < 1.E-6); } UT_REGISTER_TEST(test_md_zfmacc2); UT_REGISTER_TEST(test_md_zwavg); UT_REGISTER_TEST(test_md_zavg); UT_REGISTER_TEST(test_md_zmatmul); UT_REGISTER_TEST(test_md_zhardthresh); UT_REGISTER_TEST(test_md_zvar); UT_REGISTER_TEST(test_md_zstd); UT_REGISTER_TEST(test_md_zconv); bart-0.5.00/utests/test_flpmath_data.h000066400000000000000000000631161353046746100177270ustar00rootroot00000000000000 const complex float test_md_in0[] = { +0.000000e+00+0.000000e+00i, +2.055377e+00+1.326829e-03i, +1.195222e+00-1.464677e-01i, +1.176603e+00-8.083734e-01i, +0.000000e+00+0.000000e+00i, -3.515362e-01-1.362136e+00i, +1.680448e+00-4.103929e-01i, +5.236822e-01-3.636895e-01i, +1.681717e+00-5.943724e-01i, +1.466989e+00-1.560116e+00i, +1.437756e+00-1.145047e-01i, +0.000000e+00+0.000000e+00i, +1.261929e+00+1.136487e-01i, +1.333536e+00+1.374940e+00i, +0.000000e+00+0.000000e+00i, +2.753761e-02-6.144895e-02i, +7.782375e-01+8.355249e-01i, +9.668950e-01-6.451524e-02i, +0.000000e+00+0.000000e+00i, +1.351041e+00-5.060037e-01i, +0.000000e+00+0.000000e+00i, +4.692753e-01-1.272591e-01i, +0.000000e+00+0.000000e+00i, +1.606379e+00+8.576965e-01i, +9.275984e-01+4.085222e-01i, +1.980575e+00-2.203636e-01i, +0.000000e+00+0.000000e+00i, +8.705365e-01-1.462714e-01i, +7.474442e-01+1.056995e-01i, +3.951547e-01+7.911025e-02i, +2.356944e-01+8.030261e-01i, +1.788536e+00-6.211302e-01i, +1.135170e+00+7.936571e-01i, +1.330269e+00-7.232582e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +1.042533e+00-1.176756e+00i, +9.316891e-01-5.066474e-02i, +1.971207e+00-1.423560e-01i, +0.000000e+00+0.000000e+00i, +1.292203e+00-1.797395e+00i, +1.068649e+00-3.408340e-02i, +9.923827e-01-2.130693e-01i, +1.050540e+00+1.981200e+00i, -2.409087e-01+1.063292e+00i, +0.000000e+00+0.000000e+00i, +1.170681e+00+6.509815e-01i, +0.000000e+00+0.000000e+00i, -2.989733e-01+1.690195e+00i, +9.002356e-01+2.762856e-01i, +1.748728e+00-1.088211e+00i, +0.000000e+00+0.000000e+00i, +5.186851e-01+1.769070e+00i, +1.205285e+00+2.983286e-01i, +6.900309e-01+4.038573e-01i, +6.311213e-01-4.964017e-02i, -3.051573e-01-8.232310e-01i, +2.171920e+00+4.882384e-01i, +3.193713e-01+6.740723e-01i, +0.000000e+00+0.000000e+00i, +6.873003e-01-7.488998e-03i, +1.446579e-01-4.822526e-01i, +1.022734e+00+1.512557e-01i, +1.292160e+00-4.191149e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +3.354388e-01-1.880779e-01i, +1.023323e+00+8.066830e-01i, -2.286107e-01-4.679730e-01i, +0.000000e+00+0.000000e+00i, +1.675541e+00+8.596825e-02i, +2.613676e-01-7.391413e-02i, +8.977595e-01+3.807217e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +1.306031e+00-4.057826e-02i, +1.046151e+00+4.341971e-01i, +1.969883e+00-1.505297e+00i, +1.308183e+00+5.377352e-01i, +1.098623e+00+4.579275e-01i, +1.406074e+00+3.533691e-01i, }; const complex float test_md_in1[] = { -1.739342e+00+6.139934e-01i, +1.055377e+00+1.326829e-03i, +0.000000e+00+0.000000e+00i, +1.766032e-01-8.083734e-01i, +0.000000e+00+0.000000e+00i, -1.351536e+00-1.362136e+00i, +6.804481e-01-4.103929e-01i, -4.763178e-01-3.636895e-01i, +0.000000e+00+0.000000e+00i, +4.669890e-01-1.560116e+00i, +4.377561e-01-1.145047e-01i, +5.442010e-01+2.287491e-01i, +2.619285e-01+1.136487e-01i, +3.335362e-01+1.374940e+00i, +5.712720e-01-5.553765e-01i, -9.724624e-01-6.144895e-02i, -2.217625e-01+8.355249e-01i, -3.310501e-02-6.451524e-02i, -8.968572e-01-4.953450e-01i, +3.510412e-01-5.060037e-01i, -5.060645e-01+1.026288e-01i, -5.307246e-01-1.272591e-01i, -4.097993e-01+2.641491e-01i, +6.063793e-01+8.576965e-01i, -7.240165e-02+4.085222e-01i, +9.805748e-01-2.203636e-01i, -8.162820e-01+7.263730e-01i, -1.294635e-01-1.462714e-01i, -2.525558e-01+1.056995e-01i, +0.000000e+00+0.000000e+00i, -7.643057e-01+8.030261e-01i, +7.885358e-01-6.211302e-01i, +0.000000e+00+0.000000e+00i, +3.302687e-01-7.232582e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +9.712067e-01-1.423560e-01i, -7.432643e-02-8.247252e-01i, +2.922028e-01-1.797395e+00i, +6.864856e-02-3.408340e-02i, +0.000000e+00+0.000000e+00i, +5.054002e-02+1.981200e+00i, -1.240909e+00+1.063292e+00i, -1.493490e-01+1.064104e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, -1.298973e+00+1.690195e+00i, -9.976440e-02+2.762856e-01i, +0.000000e+00+0.000000e+00i, +3.488271e-03+1.817008e+00i, -4.813149e-01+1.769070e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, -3.688787e-01-4.964017e-02i, -1.305157e+00-8.232310e-01i, +1.171920e+00+4.882384e-01i, -6.806287e-01+6.740723e-01i, +0.000000e+00+0.000000e+00i, -3.126998e-01-7.488998e-03i, -8.553421e-01-4.822526e-01i, +0.000000e+00+0.000000e+00i, +2.921597e-01-4.191149e-01i, +6.834013e-01+7.885104e-02i, +3.068649e-01-2.382343e+00i, -6.645612e-01-1.880779e-01i, +0.000000e+00+0.000000e+00i, -1.228611e+00-4.679730e-01i, +2.430212e-02-1.069518e+00i, +6.755413e-01+8.596825e-02i, -7.386324e-01-7.391413e-02i, +0.000000e+00+0.000000e+00i, -2.375880e-01+3.568163e-01i, +4.391219e-01+1.319193e-01i, +3.060309e-01-4.057826e-02i, +4.615126e-02+4.341971e-01i, +9.698826e-01-1.505297e+00i, +3.081829e-01+5.377352e-01i, +0.000000e+00+0.000000e+00i, +4.060740e-01+3.533691e-01i, }; const complex float test_md_zwavg_1_out[] = { +1.625299e+00-7.257044e-02i, +4.125334e-01-1.085255e+00i, +1.295282e+00-4.561516e-01i, +1.452373e+00-8.373104e-01i, +1.297733e+00+7.442943e-01i, +5.908900e-01+2.365202e-01i, +1.351041e+00-5.060037e-01i, +1.037827e+00+3.652187e-01i, +1.454087e+00+9.407929e-02i, +6.710451e-01+1.284612e-02i, +1.053133e+00+3.251843e-01i, +1.330269e+00-7.232582e-01i, +1.315143e+00-4.565923e-01i, +1.180426e+00-9.157392e-01i, +6.006714e-01+9.438076e-01i, +1.170681e+00+6.509815e-01i, +7.833301e-01+2.927565e-01i, +8.619850e-01+1.033699e+00i, +3.386649e-01-1.563379e-01i, +1.245646e+00+5.811554e-01i, +6.182307e-01-1.128286e-01i, +1.292160e+00-4.191149e-01i, +3.767170e-01+5.021071e-02i, +9.684543e-01+6.027058e-03i, +8.977595e-01+3.807217e-01i, +1.440688e+00-3.705594e-01i, +1.270960e+00+4.496773e-01i, }; const complex float test_md_zwavg_2_out[] = { +1.428525e+00-6.093832e-01i, +1.289530e+00-1.811813e-01i, +8.418009e-01-7.009920e-01i, +9.188186e-01-5.026388e-01i, +1.183177e+00+6.986534e-01i, +9.668950e-01-6.451524e-02i, +6.984369e-01+1.406315e-01i, +1.665808e+00-3.631836e-01i, +1.606379e+00+8.576965e-01i, +8.121666e-01-2.216784e-02i, +1.267990e+00-2.577154e-01i, +7.651623e-01+4.363837e-01i, +1.017458e+00-6.949127e-01i, +1.091477e+00+4.438007e-02i, +9.329824e-01+2.956175e-01i, -2.989733e-01+1.690195e+00i, +8.632006e-01+8.987792e-01i, +1.477006e+00-3.949412e-01i, +1.183084e+00+2.948689e-01i, +3.650502e-01+4.739318e-02i, +3.587884e-01-3.359876e-01i, +8.137994e-01-3.035964e-01i, +1.349432e+00+4.463256e-01i, +1.637845e-02-2.709436e-01i, +1.170658e+00+2.926262e-01i, +1.072387e+00+4.460623e-01i, +1.687979e+00-5.759639e-01i, }; const complex float test_md_zwavg_3_out[] = { +1.137359e+00-5.263007e-01i, +1.038983e+00+7.478981e-02i, +1.266974e+00+8.251847e-02i, +9.289721e-01+4.154758e-02i, +1.013537e+00-4.622906e-02i, +8.741069e-01+5.994416e-01i, +6.702473e-01+4.435137e-02i, +7.265366e-01-4.273811e-02i, +1.290386e+00+8.829648e-02i, }; const complex float test_md_zwavg_4_out[] = { +1.466989e+00-1.560116e+00i, +1.614725e+00-2.063939e-01i, +1.195222e+00-1.464677e-01i, +9.692690e-01-2.739946e-01i, +1.333536e+00+1.374940e+00i, +6.274214e-01-2.522198e-01i, +8.785281e-01-2.110656e-02i, +1.094165e+00+8.382394e-02i, +1.324306e+00-3.294438e-01i, +9.565347e-01-6.615137e-01i, +9.499381e-01+2.353387e-01i, +1.183181e+00-3.162287e-02i, -3.163945e-02+1.246611e+00i, +1.326992e+00-7.140799e-01i, +1.317516e+00-1.095458e-01i, +1.161326e+00-4.681638e-01i, +7.846125e-01+1.875135e+00i, +4.821881e-01+6.808103e-01i, +9.599834e-01+1.218214e-01i, +6.311213e-01-4.964017e-02i, -3.051573e-01-8.232310e-01i, +1.271130e+00+8.652741e-02i, +7.962818e-01+6.383175e-01i, +8.706361e-01-9.866350e-01i, +9.977416e-01+2.651231e-01i, +9.729407e-01+2.054772e-02i, +8.967251e-01+1.435702e-01i, }; const complex float test_md_zwavg_5_out[] = { +1.501277e+00-4.651531e-01i, +9.160311e-01+8.086115e-03i, +1.070836e+00-5.884194e-02i, +1.018464e+00-9.717958e-02i, +9.837804e-01+2.793014e-03i, +8.093755e-01+6.959271e-01i, +6.411828e-01-1.014814e-01i, +9.929384e-01+2.515808e-02i, +9.505602e-01+1.278250e-01i, }; const complex float test_md_zwavg_6_out[] = { +1.001483e+00-3.493457e-01i, +1.351458e+00+1.438900e-01i, +1.019735e+00-2.619590e-01i, +6.954071e-01+3.897768e-02i, +1.050002e+00+2.892558e-01i, +1.040469e+00+1.385339e-01i, +1.086103e+00+1.444116e-01i, +8.483983e-01+2.752793e-01i, +6.877151e-01-3.942984e-01i, }; const complex float test_md_zwavg_7_out[] = { +1.135224e+00-1.446307e-01i, +9.455114e-01+1.675072e-01i, +8.930431e-01+3.411703e-02i, }; const complex float test_md_zwavg_8_out[] = { +7.802837e-01+1.287929e-01i, +1.144647e+00+1.912872e-02i, +4.284065e-01-2.968628e-01i, +1.194739e+00+1.609637e-01i, +1.053954e+00+2.647105e-02i, +3.918169e-01-2.842394e-01i, +1.232672e+00-3.803800e-01i, +3.341700e-01-4.229711e-01i, +1.352226e+00-2.215583e-01i, +1.267227e+00-1.051996e+00i, +1.184723e+00-8.258472e-02i, +1.971207e+00-1.423560e-01i, +7.986839e-01-3.721460e-02i, +1.216354e+00+1.280760e-01i, +4.200192e-01-2.510282e-01i, +5.099602e-01-1.372591e-01i, +1.168106e+00+9.675643e-01i, +3.291180e-01+3.082876e-01i, +8.977595e-01+3.807217e-01i, +1.260861e+00+7.248890e-02i, +0.000000e+00+0.000000e+00i, +4.921110e-01+5.074525e-01i, +9.731933e-01+3.552414e-01i, +1.774997e+00-5.786039e-01i, +1.117891e+00+4.731287e-01i, +1.199294e+00+6.688780e-01i, +1.305680e+00+3.258488e-01i, }; const complex float test_md_zwavg_9_out[] = { +7.849661e-01-7.195204e-02i, +9.251084e-01-4.663655e-03i, +1.010116e+00-3.471713e-01i, +1.357056e+00-5.772520e-01i, +8.694955e-01-2.746537e-02i, +6.889491e-01+4.441297e-01i, +1.139827e+00+1.752332e-01i, +1.093464e+00+6.212860e-02i, +1.206432e+00+5.149413e-01i, }; const complex float test_md_zwavg_10_out[] = { +1.105350e+00-5.008288e-02i, +8.871700e-01-1.050877e-01i, +6.819006e-01-2.717406e-01i, +9.169958e-01-5.007049e-01i, +1.190353e+00+3.902190e-01i, +6.330999e-01+4.674171e-02i, +7.683123e-01+4.748894e-01i, +1.152285e+00+4.088706e-01i, +1.587270e+00-2.168228e-01i, }; const complex float test_md_zwavg_11_out[] = { +9.011952e-01-1.381119e-01i, +9.400189e-01-4.892006e-03i, +1.145123e+00+2.570732e-01i, }; const complex float test_md_zwavg_12_out[] = { +1.043335e+00-4.196132e-01i, +1.189301e+00+5.313500e-03i, +8.141066e-01-2.582361e-01i, +8.322397e-01+2.413524e-01i, +1.100479e+00+1.639504e-01i, +9.926661e-01-4.009067e-01i, +9.933884e-01-6.705729e-02i, +9.713178e-01+5.079231e-01i, +9.004521e-01+1.619205e-01i, }; const complex float test_md_zwavg_13_out[] = { +1.049503e+00-2.066723e-01i, +9.686334e-01+1.236934e-02i, +9.557921e-01+2.148831e-01i, }; const complex float test_md_zwavg_14_out[] = { +9.462690e-01-5.029815e-02i, +1.081773e+00+2.385560e-01i, +9.171251e-01-1.503249e-01i, }; const complex float test_md_zwavg_15_out[] = { +9.865393e-01+2.436269e-02i, }; const complex float* test_md_zwavg_out[] = { test_md_in0, test_md_zwavg_1_out, test_md_zwavg_2_out, test_md_zwavg_3_out, test_md_zwavg_4_out, test_md_zwavg_5_out, test_md_zwavg_6_out, test_md_zwavg_7_out, test_md_zwavg_8_out, test_md_zwavg_9_out, test_md_zwavg_10_out, test_md_zwavg_11_out, test_md_zwavg_12_out, test_md_zwavg_13_out, test_md_zwavg_14_out, test_md_zwavg_15_out }; const complex float test_md_zavg_1_out[] = { +1.083533e+00-4.838029e-02i, +2.750223e-01-7.235031e-01i, +1.295282e+00-4.561516e-01i, +9.682484e-01-5.582069e-01i, +8.651551e-01+4.961962e-01i, +5.908900e-01+2.365203e-01i, +4.503470e-01-1.686679e-01i, +6.918848e-01+2.434791e-01i, +9.693911e-01+6.271953e-02i, +6.710452e-01+1.284612e-02i, +1.053133e+00+3.251843e-01i, +4.434230e-01-2.410861e-01i, +1.315143e+00-4.565923e-01i, +7.869507e-01-6.104928e-01i, +6.006714e-01+9.438076e-01i, +3.902270e-01+2.169938e-01i, +7.833301e-01+2.927565e-01i, +5.746567e-01+6.891329e-01i, +3.386650e-01-1.563380e-01i, +8.304304e-01+3.874369e-01i, +6.182308e-01-1.128286e-01i, +4.307200e-01-1.397050e-01i, +3.767170e-01+5.021071e-02i, +6.456362e-01+4.018039e-03i, +2.992532e-01+1.269072e-01i, +1.440688e+00-3.705594e-01i, +1.270960e+00+4.496773e-01i, }; const complex float test_md_zavg_2_out[] = { +9.523503e-01-4.062555e-01i, +8.596864e-01-1.207876e-01i, +8.418009e-01-7.009920e-01i, +9.188186e-01-5.026388e-01i, +1.183177e+00+6.986534e-01i, +3.222983e-01-2.150508e-02i, +4.656246e-01+9.375437e-02i, +1.110539e+00-2.421224e-01i, +5.354597e-01+2.858988e-01i, +8.121666e-01-2.216784e-02i, +8.453268e-01-1.718103e-01i, +5.101082e-01+2.909225e-01i, +6.783053e-01-4.632751e-01i, +1.091477e+00+4.438007e-02i, +9.329824e-01+2.956176e-01i, -9.965777e-02+5.633984e-01i, +8.632006e-01+8.987791e-01i, +9.846710e-01-2.632942e-01i, +1.183084e+00+2.948689e-01i, +3.650502e-01+4.739318e-02i, +2.391922e-01-2.239918e-01i, +5.425329e-01-2.023976e-01i, +8.996214e-01+2.975504e-01i, +1.091897e-02-1.806290e-01i, +1.170658e+00+2.926262e-01i, +7.149247e-01+2.973749e-01i, +1.125319e+00-3.839760e-01i, }; const complex float test_md_zavg_3_out[] = { +8.846125e-01-4.093450e-01i, +8.080978e-01+5.816986e-02i, +7.038743e-01+4.584359e-02i, +7.225339e-01+3.231478e-02i, +9.009216e-01-4.109250e-02i, +5.827379e-01+3.996278e-01i, +5.957754e-01+3.942344e-02i, +4.843578e-01-2.849207e-02i, +1.003634e+00+6.867504e-02i, }; const complex float test_md_zavg_4_out[] = { +4.889964e-01-5.200387e-01i, +1.614725e+00-2.063939e-01i, +3.984073e-01-4.882257e-02i, +9.692690e-01-2.739946e-01i, +4.445120e-01+4.583133e-01i, +4.182809e-01-1.681465e-01i, +8.785281e-01-2.110656e-02i, +1.094165e+00+8.382394e-02i, +8.828707e-01-2.196292e-01i, +6.376898e-01-4.410091e-01i, +9.499382e-01+2.353387e-01i, +7.887872e-01-2.108192e-02i, -2.109297e-02+8.310737e-01i, +1.326992e+00-7.140799e-01i, +1.317516e+00-1.095458e-01i, +7.742172e-01-3.121092e-01i, +5.230750e-01+1.250090e+00i, +3.214588e-01+4.538736e-01i, +9.599835e-01+1.218214e-01i, +2.103738e-01-1.654672e-02i, -1.017191e-01-2.744103e-01i, +1.271130e+00+8.652741e-02i, +7.962818e-01+6.383175e-01i, +5.804241e-01-6.577567e-01i, +6.651611e-01+1.767487e-01i, +9.729406e-01+2.054772e-02i, +8.967252e-01+1.435702e-01i, }; const complex float test_md_zavg_5_out[] = { +8.340428e-01-2.584184e-01i, +6.106874e-01+5.390743e-03i, +9.518545e-01-5.230394e-02i, +7.921384e-01-7.558411e-02i, +8.744715e-01+2.482679e-03i, +5.395837e-01+4.639514e-01i, +3.562127e-01-5.637856e-02i, +8.826119e-01+2.236274e-02i, +8.449424e-01+1.136222e-01i, }; const complex float test_md_zavg_6_out[] = { +7.789312e-01-2.717133e-01i, +1.051134e+00+1.119145e-01i, +5.665196e-01-1.455328e-01i, +4.636047e-01+2.598512e-02i, +9.333349e-01+2.571163e-01i, +8.092539e-01+1.077486e-01i, +9.654248e-01+1.283658e-01i, +6.598654e-01+2.141062e-01i, +4.584768e-01-2.628656e-01i, }; const complex float test_md_zavg_7_out[] = { +7.988615e-01-1.017772e-01i, +7.353978e-01+1.302833e-01i, +6.945891e-01+2.653547e-02i, }; const complex float test_md_zavg_8_out[] = { +5.201892e-01+8.586197e-02i, +1.144647e+00+1.912872e-02i, +4.284065e-01-2.968628e-01i, +1.194739e+00+1.609637e-01i, +7.026358e-01+1.764737e-02i, +2.612113e-01-1.894930e-01i, +1.232672e+00-3.803800e-01i, +2.227800e-01-2.819807e-01i, +9.014837e-01-1.477056e-01i, +1.267227e+00-1.051996e+00i, +7.898151e-01-5.505648e-02i, +6.570690e-01-4.745200e-02i, +5.324559e-01-2.480973e-02i, +1.216354e+00+1.280760e-01i, +2.800128e-01-1.673521e-01i, +3.399734e-01-9.150609e-02i, +1.168106e+00+9.675643e-01i, +3.291180e-01+3.082876e-01i, +2.992532e-01+1.269072e-01i, +8.405740e-01+4.832594e-02i, +0.000000e+00+0.000000e+00i, +4.921110e-01+5.074525e-01i, +6.487955e-01+2.368276e-01i, +1.774997e+00-5.786039e-01i, +7.452605e-01+3.154191e-01i, +1.199294e+00+6.688780e-01i, +8.704531e-01+2.172326e-01i, }; const complex float test_md_zavg_9_out[] = { +6.977476e-01-6.395737e-02i, +7.195287e-01-3.627287e-03i, +7.856454e-01-2.700221e-01i, +9.047038e-01-3.848347e-01i, +6.762742e-01-2.136195e-02i, +6.123992e-01+3.947820e-01i, +3.799424e-01+5.841105e-02i, +9.719678e-01+5.522542e-02i, +9.383361e-01+4.005099e-01i, }; const complex float test_md_zavg_10_out[] = { +9.825337e-01-4.451812e-02i, +6.900211e-01-8.173487e-02i, +5.303672e-01-2.113538e-01i, +7.132189e-01-3.894371e-01i, +1.058092e+00+3.468613e-01i, +4.220666e-01+3.116114e-02i, +5.122082e-01+3.165930e-01i, +8.962214e-01+3.180105e-01i, +8.818166e-01-1.204571e-01i, }; const complex float test_md_zavg_11_out[] = { +7.343072e-01-1.125356e-01i, +7.311258e-01-3.804893e-03i, +7.634155e-01+1.713821e-01i, }; const complex float test_md_zavg_12_out[] = { +6.955566e-01-2.797422e-01i, +9.250122e-01+4.132722e-03i, +3.618251e-01-1.147716e-01i, +7.397687e-01+2.145355e-01i, +8.559285e-01+1.275170e-01i, +7.720736e-01-3.118163e-01i, +7.726355e-01-5.215567e-02i, +8.633936e-01+4.514872e-01i, +7.003516e-01+1.259382e-01i, }; const complex float test_md_zavg_13_out[] = { +6.607980e-01-1.301270e-01i, +7.892569e-01+1.007872e-02i, +7.787936e-01+1.750899e-01i, }; const complex float test_md_zavg_14_out[] = { +7.359870e-01-3.912078e-02i, +8.814446e-01+1.943790e-01i, +6.114167e-01-1.002166e-01i, }; const complex float test_md_zavg_15_out[] = { +7.429494e-01+1.834721e-02i, }; const complex float* test_md_zavg_out[] = { test_md_in0, test_md_zavg_1_out, test_md_zavg_2_out, test_md_zavg_3_out, test_md_zavg_4_out, test_md_zavg_5_out, test_md_zavg_6_out, test_md_zavg_7_out, test_md_zavg_8_out, test_md_zavg_9_out, test_md_zavg_10_out, test_md_zavg_11_out, test_md_zavg_12_out, test_md_zavg_13_out, test_md_zavg_14_out, test_md_zavg_15_out }; const complex float test_md_zfmacc2_0_out[] = { +0.000000e+00+0.000000e+00i, +2.169199e+00-1.326829e-03i, +0.000000e+00+0.000000e+00i, +8.612594e-01+8.083732e-01i, +0.000000e+00+0.000000e+00i, +2.330528e+00+1.362136e+00i, +1.311880e+00+4.103929e-01i, -1.171691e-01+3.636895e-01i, +0.000000e+00+0.000000e+00i, +3.119030e+00+1.560116e+00i, +6.424978e-01+1.145047e-01i, +0.000000e+00+0.000000e+00i, +3.434512e-01-1.136488e-01i, +2.335243e+00-1.374940e+00i, +0.000000e+00+0.000000e+00i, -2.300332e-02+6.144895e-02i, +5.255180e-01-8.355249e-01i, -2.784685e-02+6.451524e-02i, +0.000000e+00+0.000000e+00i, +7.303107e-01+5.060036e-01i, +0.000000e+00+0.000000e+00i, -2.328611e-01+1.272591e-01i, +0.000000e+00+0.000000e+00i, +1.709718e+00-8.576963e-01i, +9.973073e-02-4.085222e-01i, +1.990662e+00+2.203636e-01i, +0.000000e+00+0.000000e+00i, -9.130738e-02+1.462714e-01i, -1.775990e-01-1.056995e-01i, +0.000000e+00+0.000000e+00i, +4.647083e-01-8.030262e-01i, +1.796127e+00+6.211303e-01i, +0.000000e+00+0.000000e+00i, +9.624486e-01+7.232584e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +1.934715e+00+1.423560e-01i, +0.000000e+00+0.000000e+00i, +3.608214e+00+1.797395e+00i, +7.452290e-02+3.408341e-02i, +0.000000e+00+0.000000e+00i, +3.978248e+00-1.981200e+00i, +1.429536e+00-1.063292e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +3.245117e+00-1.690194e+00i, -1.347774e-02-2.762856e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +2.879958e+00-1.769070e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, -2.303430e-01+4.964017e-02i, +1.075987e+00+8.232306e-01i, +2.783693e+00-4.882385e-01i, +2.370002e-01-6.740724e-01i, +0.000000e+00+0.000000e+00i, -2.148626e-01+7.488999e-03i, +1.088356e-01+4.822526e-01i, +0.000000e+00+0.000000e+00i, +5.531744e-01+4.191150e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, -1.875463e-01+1.880779e-01i, +0.000000e+00+0.000000e+00i, +4.998724e-01+4.679731e-01i, +0.000000e+00+0.000000e+00i, +1.139288e+00-8.596823e-02i, -1.875913e-01+7.391413e-02i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +4.013324e-01+4.057826e-02i, +2.368083e-01-4.341970e-01i, +4.176474e+00+1.505298e+00i, +6.923188e-01-5.377352e-01i, +0.000000e+00+0.000000e+00i, +6.958398e-01-3.533691e-01i, }; const complex float test_md_zfmacc2_1_out[] = { +2.169199e+00-1.326829e-03i, +3.191788e+00+2.170509e+00i, +1.194711e+00+7.740824e-01i, +3.761528e+00+1.674621e+00i, +2.678694e+00-1.488589e+00i, +4.746678e-01-7.095608e-01i, +7.303107e-01+5.060036e-01i, +1.476857e+00-7.304372e-01i, +2.090393e+00-1.881585e-01i, -2.689064e-01+4.057188e-02i, +2.260836e+00-1.818959e-01i, +9.624486e-01+7.232584e-01i, +1.934715e+00+1.423560e-01i, +3.682737e+00+1.831479e+00i, +5.407784e+00-3.044492e+00i, +0.000000e+00+0.000000e+00i, +3.231639e+00-1.966480e+00i, +2.879958e+00-1.769070e+00i, +8.456444e-01+8.728708e-01i, +3.020694e+00-1.162311e+00i, -1.060270e-01+4.897416e-01i, +5.531744e-01+4.191150e-01i, +3.123260e-01+6.560510e-01i, +9.516963e-01-1.205409e-02i, +0.000000e+00+0.000000e+00i, +4.814615e+00+1.111679e+00i, +1.388159e+00-8.911043e-01i, }; const complex float test_md_zfmacc2_2_out[] = { +2.173140e+00+1.218766e+00i, +2.052030e+00+3.623627e-01i, +2.330528e+00+1.362136e+00i, +3.439478e+00+1.507916e+00i, +3.503258e+00-2.095960e+00i, -2.784685e-02+6.451524e-02i, -1.331303e-01-2.812631e-01i, +2.720973e+00+7.263672e-01i, +1.709718e+00-8.576963e-01i, +1.335850e+00+6.650358e-02i, +1.618528e+00+5.154309e-01i, +0.000000e+00+0.000000e+00i, +0.000000e+00+0.000000e+00i, +7.586462e+00-1.838046e-01i, +3.438773e+00-8.868529e-01i, +3.245117e+00-1.690194e+00i, +2.866480e+00-2.045356e+00i, +0.000000e+00+0.000000e+00i, +2.568831e+00-4.807495e-01i, +1.154928e-01-1.421796e-01i, +1.075987e+00+8.232306e-01i, +3.656281e-01+6.071929e-01i, +1.139288e+00-8.596823e-02i, +3.122811e-01+5.418873e-01i, +1.093651e+00-4.971570e-01i, +2.368083e-01-4.341970e-01i, +4.872314e+00+1.151928e+00i, }; const complex float test_md_zfmacc2_3_out[] = { +6.555697e+00+2.943265e+00i, +6.914890e+00-5.235287e-01i, +4.297561e+00-4.125923e-01i, +2.954378e+00+5.819345e-01i, +1.102523e+01-1.070657e+00i, +6.111597e+00-3.735550e+00i, +3.760310e+00+2.003016e-01i, +1.817197e+00+1.063112e+00i, +6.202774e+00+2.205745e-01i, }; const complex float test_md_zfmacc2_4_out[] = { +3.119030e+00+1.560116e+00i, +3.542008e+00+6.191815e-01i, +0.000000e+00+0.000000e+00i, +9.718496e-01+8.219835e-01i, +2.335243e+00-1.374940e+00i, +4.040246e+00+5.044395e-01i, +1.388608e+00+6.331962e-02i, +2.399011e+00-2.514718e-01i, -2.784685e-02+6.451524e-02i, -9.130738e-02+1.462714e-01i, -1.775990e-01-1.056995e-01i, +1.934715e+00+1.423560e-01i, +3.709826e+00-2.493221e+00i, +5.390864e+00+2.142240e+00i, +7.452290e-02+3.408341e-02i, +9.624486e-01+7.232584e-01i, +6.858206e+00-3.750270e+00i, +1.429536e+00-1.063292e+00i, +5.531744e-01+4.191150e-01i, -2.303430e-01+4.964017e-02i, +1.075987e+00+8.232306e-01i, +2.997479e+00-2.595823e-01i, +4.738085e-01-1.108269e+00i, +4.676347e+00+1.973271e+00i, +4.774562e-01-5.302463e-01i, +1.248123e+00+3.962843e-01i, +5.082486e-01-2.794550e-01i, }; const complex float test_md_zfmacc2_5_out[] = { +6.661037e+00+2.179297e+00i, +7.347339e+00-4.851699e-02i, +3.759772e+00-1.236369e-01i, +1.665808e+00+1.829279e-01i, +9.175213e+00-3.168970e-01i, +9.250190e+00-4.090304e+00i, +1.398819e+00+1.291986e+00i, +8.147635e+00+6.054189e-01i, +2.233828e+00-4.134169e-01i, }; const complex float test_md_zfmacc2_6_out[] = { +5.479487e+00+2.445419e+00i, +8.276260e+00-1.007230e+00i, +4.012400e+00+5.689547e-01i, +4.580967e+00-1.623691e+00i, +1.207147e+01-1.713729e+00i, +3.438773e+00-8.868529e-01i, +4.028110e+00-3.707135e-01i, +1.491589e+00-6.623448e-01i, +6.260583e+00+2.517046e+00i, }; const complex float test_md_zfmacc2_7_out[] = { +1.776814e+01+2.007144e+00i, +2.009121e+01-4.224273e+00i, +1.178028e+01+1.483988e+00i, }; const complex float test_md_zfmacc2_8_out[] = { -9.130738e-02+1.462714e-01i, +1.761257e+00-5.738616e-02i, +1.075987e+00+8.232306e-01i, +4.109661e+00-4.828914e-01i, +2.033128e+00-5.294201e-02i, +2.330528e+00+1.362136e+00i, +2.059466e+00+1.141140e+00i, -8.333489e-03+8.459420e-01i, +0.000000e+00+0.000000e+00i, +3.672204e+00+1.979231e+00i, +6.424978e-01+1.145047e-01i, +1.934715e+00+1.423560e-01i, +1.559049e-01+7.442913e-02i, +5.943457e+00+4.224555e-01i, +5.743952e-01+5.020566e-01i, -2.300332e-02+6.144895e-02i, +5.643053e+00-2.902693e+00i, +1.214097e+00-9.248629e-01i, +0.000000e+00+0.000000e+00i, +7.303107e-01+5.060036e-01i, +0.000000e+00+0.000000e+00i, +3.413589e+00-1.522357e+00i, +2.233306e-01-7.104826e-01i, +5.886192e+00+6.476014e-01i, +7.920495e-01-9.462575e-01i, +4.870620e+00-1.548706e+00i, +6.958398e-01-3.533691e-01i, }; const complex float test_md_zfmacc2_9_out[] = { +2.745937e+00+9.121158e-01i, +8.473317e+00+8.263025e-01i, +2.051133e+00+1.987082e+00i, +6.249417e+00+2.236092e+00i, +6.673758e+00+9.989411e-01i, +6.834147e+00-3.766107e+00i, +7.303107e-01+5.060036e-01i, +9.523111e+00-1.585239e+00i, +6.358510e+00-2.848333e+00i, }; const complex float test_md_zfmacc2_10_out[] = { +6.077820e+00+8.045202e-01i, +3.786051e+00+7.356139e-01i, +3.406516e+00+2.185366e+00i, +3.805106e+00+2.115109e+00i, +1.222901e+01-2.365733e+00i, +3.723207e+00-2.804503e-01i, +4.205638e+00-2.468614e+00i, +5.824261e+00-1.753185e+00i, +6.582032e+00+2.942323e-01i, }; const complex float test_md_zfmacc2_11_out[] = { +1.327039e+01+3.725501e+00i, +1.975732e+01-5.310741e-01i, +1.661193e+01-3.927568e+00i, }; const complex float test_md_zfmacc2_12_out[] = { +3.580897e+00+2.125503e+00i, +3.134065e+00+5.631222e-01i, +3.010702e+00+9.655867e-01i, +7.679154e+00-1.930819e+00i, +8.199914e+00-3.409690e-01i, +8.791117e+00+2.511794e+00i, +2.828512e+00+2.563318e-01i, +1.050534e+01-3.605457e+00i, +1.909937e+00-1.278232e+00i, }; const complex float test_md_zfmacc2_13_out[] = { +9.725664e+00+3.654212e+00i, +2.467019e+01+2.400053e-01i, +1.524379e+01-4.627357e+00i, }; const complex float test_md_zfmacc2_14_out[] = { +1.408856e+01+4.510146e-01i, +2.183932e+01-3.383304e+00i, +1.371176e+01+2.199148e+00i, }; const complex float test_md_zfmacc2_15_out[] = { +4.963963e+01-7.331403e-01i, }; const complex float* test_md_zfmacc2_out[] = { test_md_zfmacc2_0_out, test_md_zfmacc2_1_out, test_md_zfmacc2_2_out, test_md_zfmacc2_3_out, test_md_zfmacc2_4_out, test_md_zfmacc2_5_out, test_md_zfmacc2_6_out, test_md_zfmacc2_7_out, test_md_zfmacc2_8_out, test_md_zfmacc2_9_out, test_md_zfmacc2_10_out, test_md_zfmacc2_11_out, test_md_zfmacc2_12_out, test_md_zfmacc2_13_out, test_md_zfmacc2_14_out, test_md_zfmacc2_15_out, }; bart-0.5.00/utests/test_linalg.c000066400000000000000000000025051353046746100165370ustar00rootroot00000000000000/* Copyright 2016-2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016-2019 Martin Uecker */ #include #include "num/linalg.h" #include "utest.h" static bool test_mat_pinv(void) { const complex float A[3][2] = { { 1.i, 4. }, { 2.i, 5. }, { 3.i, 6. }, }; const complex float C[2][3] = { { -0.00000 + 0.94444i, +0.00000 + 0.11111i, +0.00000 - 0.72222i }, { +0.44444 + 0.00000i, +0.11111 + 0.00000i, +-0.22222 - 0.00000i }, }; complex float B[2][3]; mat_pinv(3, 2, B, A); float err = 0.; for (int i = 0; i < 2; i++) for (int j = 0; j < 3; j++) err += powf(cabsf(C[i][j] - B[i][j]), 2.); return (err < 1.E-10); } UT_REGISTER_TEST(test_mat_pinv); static bool test_thomas_algorithm(void) { const complex float A[7][3] = { { 0. , 1., 0.5 }, { 0.5, 1., 0.5 }, { 0.5, 1., 0.5 }, { 0.5, 1., 0.5 }, { 0.5, 1., 0.5 }, { 0.5, 1., 0.5 }, { 0.5, 1., 0. }, }; const complex float d[7] = { 1., 0., 0., 0., 0., 0., 0. }; complex float x[7]; thomas_algorithm(7, x, A, d); bool ok = true; for (int i = 0; i < 7; i++) ok &= (cabsf(x[i] - 0.25f * (7 - i) * powf(-1., i)) < 1e-6); return ok; } UT_REGISTER_TEST(test_thomas_algorithm); bart-0.5.00/utests/test_linop.c000066400000000000000000000033421353046746100164120ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "num/ops.h" #include "linops/someops.h" #include "linops/linop.h" #include "misc/misc.h" #include "misc/debug.h" #include "utest.h" static bool test_linop_plus(void) { enum { N = 3 }; long dims[N] = { 8, 4, 2 }; complex float val1a = 2.; complex float val1b = 3.; struct linop_s* diaga = linop_cdiag_create(N, dims, 0, &val1a); struct linop_s* diagb = linop_cdiag_create(N, dims, 0, &val1b); struct linop_s* plus = linop_plus(diaga, diagb); complex float val2 = 5.; struct linop_s* diag2 = linop_cdiag_create(N, dims, 0, &val2); complex float* in = md_alloc(N, dims, CFL_SIZE); complex float* dst1 = md_alloc(N, dims, CFL_SIZE); complex float* dst2 = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, in); linop_forward(plus, N, dims, dst1, N, dims, in); linop_forward(diag2, N, dims, dst2, N, dims, in); double err = md_znrmse(N, dims, dst1, dst2); linop_free(diaga); linop_free(diagb); linop_free(plus); linop_free(diag2); md_free(in); md_free(dst1); md_free(dst2); return (err < UT_TOL); } UT_REGISTER_TEST(test_linop_plus); static bool test_linop_null(void) { long dims[1] = { 5 }; const struct linop_s* l = linop_null_create(1, dims, dims); bool ok = true; ok &= operator_zero_or_null_p(l->forward); ok &= operator_zero_or_null_p(l->adjoint); ok &= operator_zero_or_null_p(l->normal); linop_free(l); return ok; } UT_REGISTER_TEST(test_linop_null); bart-0.5.00/utests/test_linop_matrix.c000066400000000000000000000100441353046746100177730ustar00rootroot00000000000000/* Copyright 2017. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "linops/someops.h" #include "linops/linop.h" #include "linops/lintest.h" #include "misc/misc.h" #include "misc/debug.h" #include "utest.h" static bool test_linop_matrix(void) { enum { N = 3 }; int A = 2; int B = 3; int C = 4; long odims[N] = { C, 1, A }; long idims1[N] = { 1, B, A }; long idims2[N] = { C, B, 1 }; complex float* dst1 = md_alloc(N, odims, CFL_SIZE); complex float* dst2 = md_alloc(N, odims, CFL_SIZE); complex float* src1 = md_alloc(N, idims1, CFL_SIZE); complex float* src2 = md_alloc(N, idims2, CFL_SIZE); md_gaussian_rand(N, odims, dst1); // test complete fill md_gaussian_rand(N, odims, dst2); // test complete fill md_gaussian_rand(N, idims1, src1); md_gaussian_rand(N, idims2, src2); struct linop_s* mat = linop_matrix_create(N, odims, idims2, idims1, src1); md_zmatmul(N, odims, dst1, idims1, src1, idims2, src2); linop_forward(mat, N, odims, dst2, N, idims2, src2); double err = md_znrmse(N, odims, dst2, dst1); linop_free(mat); md_free(src1); md_free(src2); md_free(dst1); md_free(dst2); return (err < UT_TOL); } static bool test_linop_matrix_adjoint(void) { enum { N = 3 }; int A = 2; int B = 3; int C = 4; long odims[N] = { C, 1, A }; long idims1[N] = { 1, B, A }; long idims2[N] = { C, B, 1 }; complex float* src1 = md_alloc(N, idims1, CFL_SIZE); md_gaussian_rand(N, idims1, src1); struct linop_s* mat = linop_matrix_create(N, odims, idims2, idims1, src1); float diff = linop_test_adjoint(mat); debug_printf(DP_DEBUG1, "adjoint diff: %f\n", diff); bool ret = (diff < 1.E-4f); linop_free(mat); md_free(src1); return ret; } static bool test_linop_matrix_normal(void) { enum { N = 3 }; int A = 2; int B = 3; int C = 4; long odims[N] = { C, 1, A }; long idims1[N] = { 1, B, A }; long idims2[N] = { C, B, 1 }; complex float* src1 = md_alloc(N, idims1, CFL_SIZE); md_gaussian_rand(N, idims1, src1); struct linop_s* mat = linop_matrix_create(N, odims, idims2, idims1, src1); float nrmse = linop_test_normal(mat); debug_printf(DP_DEBUG1, "normal nrmse: %f\n", nrmse); bool ret = (nrmse < 1.E-6f); linop_free(mat); md_free(src1); return ret; } static bool test_linop_matrix_chain(void) { int A = 9; int B = 7; int C = 3; int D = 2; int E = 5; enum { N = 8 }; long odims[N] = { D, C, 1, 1, 1, 1, C, D }; long idims0[N] = { D, 1, 1, A, E, 1, A, D }; long idims1[N] = { D, 1, B, A, 1, B, A, D }; long tdims[N] = { D, 1, B, 1, E, B, 1, D }; long idims2[N] = { D, C, B, 1, E, B, C, D }; complex float* dst1 = md_alloc(N, odims, CFL_SIZE); complex float* dst2 = md_alloc(N, odims, CFL_SIZE); complex float* src0 = md_alloc(N, idims0, CFL_SIZE); complex float* src1 = md_alloc(N, idims1, CFL_SIZE); complex float* src2 = md_alloc(N, idims2, CFL_SIZE); md_gaussian_rand(N, odims, dst1); // test complete fill md_gaussian_rand(N, odims, dst2); // test complete fill md_gaussian_rand(N, idims0, src0); md_gaussian_rand(N, idims1, src1); md_gaussian_rand(N, idims2, src2); struct linop_s* mat1 = linop_matrix_create(N, tdims, idims0, idims1, src1); struct linop_s* mat2 = linop_matrix_create(N, odims, tdims, idims2, src2); struct linop_s* matA = linop_chain(mat1, mat2); linop_forward(matA, N, odims, dst1, N, idims0, src0); linop_free(matA); struct linop_s* matB = linop_matrix_chain(mat1, mat2); linop_forward(matB, N, odims, dst2, N, idims0, src0); linop_free(matB); double err = md_znrmse(N, odims, dst2, dst1); linop_free(mat1); linop_free(mat2); md_free(src0); md_free(src1); md_free(src2); md_free(dst1); md_free(dst2); return (err < 1.E-5); } UT_REGISTER_TEST(test_linop_matrix); UT_REGISTER_TEST(test_linop_matrix_adjoint); UT_REGISTER_TEST(test_linop_matrix_normal); UT_REGISTER_TEST(test_linop_matrix_chain); bart-0.5.00/utests/test_mdfft.c000066400000000000000000000014001353046746100163620ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/mdfft.h" #include "utest.h" static bool test_mdfft(void) { enum { N = 4 }; long dims[N] = { 10, 10, 1, 1 }; complex float* x = md_calloc(N, dims, sizeof(complex float)); complex float* y = md_calloc(N, dims, sizeof(complex float)); x[0] = 1.; md_fft(N, dims, 3, 0, y, x); md_zfill(N, dims, x, 1.); float err = md_znrmse(N, dims, x, y); md_free(x); md_free(y); return (err < 1.E-6); } UT_REGISTER_TEST(test_mdfft); bart-0.5.00/utests/test_moba.c000066400000000000000000000026501353046746100162100ustar00rootroot00000000000000/* Copyright 2019. Uecker Lab, University Medical Center Goettingen. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: Xiaoqing Wang, Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "num/iovec.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/mmio.h" #include "linops/linop.h" #include "linops/lintest.h" #include "linops/someops.h" #include "nlops/nlop.h" #include "moba/T1fun.h" #include "utest.h" static bool test_nlop_T1fun(void) { enum { N = 16 }; long map_dims[N] = { 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; long out_dims[N] = { 16, 16, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; long in_dims[N] = { 16, 16, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; long TI_dims[N] = { 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; complex float* dst = md_alloc(N, out_dims, CFL_SIZE); complex float* src = md_alloc(N, in_dims, CFL_SIZE); complex float TI[4] = { 0., 1., 2., 3. }; md_zfill(N, in_dims, src, 1.0); struct nlop_s* T1 = nlop_T1_create(N, map_dims, out_dims, in_dims, TI_dims, TI, false); nlop_apply(T1, N, out_dims, dst, N, in_dims, src); float err = linop_test_adjoint(nlop_get_derivative(T1, 0, 0)); nlop_free(T1); md_free(src); md_free(dst); UT_ASSERT(err < 1.E-3); } UT_REGISTER_TEST(test_nlop_T1fun); bart-0.5.00/utests/test_multind.c000066400000000000000000000052741353046746100167530ustar00rootroot00000000000000 #include #include "num/multind.h" #include "num/rand.h" #include "utest.h" static bool test_md_copy(void) { enum { N = 4 }; long dims[N] = { 10, 10, 10, 10 }; complex float* a = md_alloc(N, dims, sizeof(complex float)); md_gaussian_rand(N, dims, a); complex float* b = md_alloc(N, dims, sizeof(complex float)); md_copy(N, dims, b, a, sizeof(complex float)); bool eq = md_compare(N, dims, a, b, sizeof(complex float)); md_free(a); md_free(b); return eq; } UT_REGISTER_TEST(test_md_copy); static bool test_md_transpose(void) { enum { N = 4 }; long dims[N] = { 10, 10, 10, 10 }; complex float* a = md_alloc(N, dims, sizeof(complex float)); md_gaussian_rand(N, dims, a); complex float* b = md_alloc(N, dims, sizeof(complex float)); complex float* c = md_alloc(N, dims, sizeof(complex float)); md_transpose(N, 0, 2, dims, b, dims, a, sizeof(complex float)); md_transpose(N, 0, 2, dims, c, dims, b, sizeof(complex float)); bool eq = md_compare(N, dims, a, c, sizeof(complex float)); md_free(a); md_free(b); md_free(c); return eq; } UT_REGISTER_TEST(test_md_transpose); static bool test_md_swap(void) { enum { N = 4 }; long dims[N] = { 10, 10, 10, 10 }; complex float* a = md_alloc(N, dims, sizeof(complex float)); complex float* b = md_alloc(N, dims, sizeof(complex float)); complex float* c = md_alloc(N, dims, sizeof(complex float)); md_gaussian_rand(N, dims, a); md_gaussian_rand(N, dims, b); md_gaussian_rand(N, dims, c); complex float* d = md_alloc(N, dims, sizeof(complex float)); complex float* e = md_alloc(N, dims, sizeof(complex float)); complex float* f = md_alloc(N, dims, sizeof(complex float)); md_copy(N, dims, d, a, sizeof(complex float)); md_copy(N, dims, e, b, sizeof(complex float)); md_copy(N, dims, f, c, sizeof(complex float)); md_circular_swap(3, N, dims, (void*[]){ a, b, c }, sizeof(complex float)); bool eq = true; eq &= md_compare(N, dims, c, d, sizeof(complex float)); eq &= md_compare(N, dims, a, e, sizeof(complex float)); eq &= md_compare(N, dims, b, f, sizeof(complex float)); md_free(a); md_free(b); md_free(c); md_free(d); md_free(e); md_free(f); return eq; } UT_REGISTER_TEST(test_md_swap); static bool test_md_flip(void) { enum { N = 4 }; long dims[N] = { 10, 10, 10, 10 }; complex float* a = md_alloc(N, dims, sizeof(complex float)); md_gaussian_rand(N, dims, a); complex float* b = md_alloc(N, dims, sizeof(complex float)); md_flip(N, dims, MD_BIT(0) | MD_BIT(2), b, a, sizeof(complex float)); md_flip(N, dims, MD_BIT(0) | MD_BIT(2), b, b, sizeof(complex float)); bool eq = md_compare(N, dims, a, b, sizeof(complex float)); md_free(a); md_free(b); return eq; } UT_REGISTER_TEST(test_md_flip); bart-0.5.00/utests/test_nlop.c000066400000000000000000000267431353046746100162530ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "num/iovec.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/mmio.h" #include "linops/linop.h" #include "linops/lintest.h" #include "linops/someops.h" #include "nlops/zexp.h" #include "nlops/tenmul.h" #include "nlops/nlop.h" #include "nlops/cast.h" #include "nlops/chain.h" #include "nlops/nltest.h" #include "utest.h" static bool test_nlop_cast_pos(void) { bool ok = true; enum { N = 3 }; long dims[N] = { 10, 7, 3 }; struct linop_s* l = linop_identity_create(N, dims); struct nlop_s* d = nlop_from_linop(l); if (l == linop_from_nlop(d)) // maybe just require != NULL ? ok = false; linop_free(l); nlop_free(d); return ok; } UT_REGISTER_TEST(test_nlop_cast_pos); static bool test_nlop_cast_neg(void) { bool ok = true; enum { N = 3 }; long dims[N] = { 10, 7, 3 }; struct nlop_s* d = nlop_zexp_create(N, dims); if (NULL != linop_from_nlop(d)) ok = false; nlop_free(d); return ok; } UT_REGISTER_TEST(test_nlop_cast_neg); static bool test_nlop_chain(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; complex float val = 2.; struct linop_s* cdiag = linop_cdiag_create(N, dims, 0, &val); struct nlop_s* diag = nlop_from_linop(cdiag); struct nlop_s* zexp = nlop_zexp_create(N, dims); struct nlop_s* zexp2 = nlop_chain(zexp, diag); double err = nlop_test_derivative(zexp2); nlop_free(zexp2); nlop_free(zexp); nlop_free(diag); linop_free(cdiag); UT_ASSERT(err < 1.E-2); } UT_REGISTER_TEST(test_nlop_chain); static bool test_nlop_tenmul(void) { enum { N = 3 }; long odims[N] = { 10, 1, 3 }; long idims1[N] = { 1, 7, 3 }; long idims2[N] = { 10, 7, 1 }; complex float* dst1 = md_alloc(N, odims, CFL_SIZE); complex float* dst2 = md_alloc(N, odims, CFL_SIZE); complex float* src1 = md_alloc(N, idims1, CFL_SIZE); complex float* src2 = md_alloc(N, idims2, CFL_SIZE); md_gaussian_rand(N, idims1, src1); md_gaussian_rand(N, idims2, src2); struct nlop_s* tenmul = nlop_tenmul_create(N, odims, idims1, idims2); md_ztenmul(N, odims, dst1, idims1, src1, idims2, src2); nlop_generic_apply_unchecked(tenmul, 3, (void*[]){ dst2, src1, src2 }); double err = md_znrmse(N, odims, dst2, dst1); nlop_free(tenmul); md_free(src1); md_free(src2); md_free(dst1); md_free(dst2); UT_ASSERT(err < UT_TOL); } UT_REGISTER_TEST(test_nlop_tenmul); static bool test_nlop_tenmul_der(void) { enum { N = 3 }; long odims[N] = { 10, 1, 3 }; long idims1[N] = { 1, 7, 3 }; long idims2[N] = { 10, 7, 1 }; complex float* dst1 = md_alloc(N, odims, CFL_SIZE); complex float* dst2 = md_alloc(N, odims, CFL_SIZE); complex float* dst3 = md_alloc(N, odims, CFL_SIZE); complex float* src1 = md_alloc(N, idims1, CFL_SIZE); complex float* src2 = md_alloc(N, idims2, CFL_SIZE); md_gaussian_rand(N, idims1, src1); md_gaussian_rand(N, idims2, src2); struct nlop_s* tenmul = nlop_tenmul_create(N, odims, idims1, idims2); nlop_generic_apply_unchecked(tenmul, 3, (void*[]){ dst1, src1, src2 }); const struct linop_s* der1 = nlop_get_derivative(tenmul, 0, 0); const struct linop_s* der2 = nlop_get_derivative(tenmul, 0, 1); linop_forward(der1, N, odims, dst2, N, idims1, src1); linop_forward(der2, N, odims, dst3, N, idims2, src2); double err = md_znrmse(N, odims, dst2, dst1) + md_znrmse(N, odims, dst3, dst1); nlop_free(tenmul); md_free(src1); md_free(src2); md_free(dst1); md_free(dst2); md_free(dst3); UT_ASSERT(err < UT_TOL); } UT_REGISTER_TEST(test_nlop_tenmul_der); static bool test_nlop_zexp(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; complex float* dst1 = md_alloc(N, dims, CFL_SIZE); complex float* dst2 = md_alloc(N, dims, CFL_SIZE); complex float* src = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, src); struct nlop_s* zexp = nlop_zexp_create(N, dims); md_zexp(N, dims, dst1, src); nlop_apply(zexp, N, dims, dst2, N, dims, src); double err = md_znrmse(N, dims, dst2, dst1); nlop_free(zexp); md_free(src); md_free(dst1); md_free(dst2); UT_ASSERT(err < UT_TOL); } UT_REGISTER_TEST(test_nlop_zexp); static bool test_nlop_tenmul_der2(void) { enum { N = 3 }; long odims[N] = { 10, 1, 3 }; long idims1[N] = { 1, 7, 3 }; long idims2[N] = { 10, 7, 1 }; struct nlop_s* tenmul = nlop_tenmul_create(N, odims, idims1, idims2); struct nlop_s* flat = nlop_flatten(tenmul); double err = nlop_test_derivative(flat); nlop_free(flat); nlop_free(tenmul); UT_ASSERT((!safe_isnanf(err)) && (err < 1.5E-2)); } UT_REGISTER_TEST(test_nlop_tenmul_der2); static void random_application(const struct nlop_s* nlop) { auto dom = nlop_domain(nlop); auto cod = nlop_codomain(nlop); complex float* in = md_alloc(dom->N, dom->dims, dom->size); complex float* dst = md_alloc(cod->N, cod->dims, cod->size); md_gaussian_rand(dom->N, dom->dims, in); // define position for derivatives nlop_apply(nlop, cod->N, cod->dims, dst, dom->N, dom->dims, in); md_free(in); md_free(dst); } static bool test_nlop_tenmul_der_adj(void) { enum { N = 3 }; long odims[N] = { 10, 1, 3 }; long idims1[N] = { 1, 7, 3 }; long idims2[N] = { 10, 7, 1 }; struct nlop_s* tenmul = nlop_tenmul_create(N, odims, idims1, idims2); struct nlop_s* flat = nlop_flatten(tenmul); random_application(flat); double err = linop_test_adjoint(nlop_get_derivative(flat, 0, 0)); nlop_free(flat); nlop_free(tenmul); UT_ASSERT((!safe_isnanf(err)) && (err < 6.E-2)); } UT_REGISTER_TEST(test_nlop_tenmul_der_adj); static bool test_nlop_zexp_derivative(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; struct nlop_s* zexp = nlop_zexp_create(N, dims); double err = nlop_test_derivative(zexp); nlop_free(zexp); UT_ASSERT(err < 1.E-2); } UT_REGISTER_TEST(test_nlop_zexp_derivative); static bool test_nlop_zexp_der_adj(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; struct nlop_s* zexp = nlop_zexp_create(N, dims); complex float* dst = md_alloc(N, dims, CFL_SIZE); complex float* src = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, src); nlop_apply(zexp, N, dims, dst, N, dims, src); md_free(src); md_free(dst); float err = linop_test_adjoint(nlop_get_derivative(zexp, 0, 0)); nlop_free(zexp); UT_ASSERT(err < 1.E-2); } UT_REGISTER_TEST(test_nlop_zexp_der_adj); static bool test_nlop_combine(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; struct nlop_s* zexp = nlop_zexp_create(N, dims); struct linop_s* lid = linop_identity_create(N, dims); struct nlop_s* id = nlop_from_linop(lid); linop_free(lid); struct nlop_s* comb = nlop_combine(zexp, id); complex float* in1 = md_alloc(N, dims, CFL_SIZE); complex float* in2 = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, in1); md_gaussian_rand(N, dims, in2); complex float* out1 = md_alloc(N, dims, CFL_SIZE); complex float* out2 = md_alloc(N, dims, CFL_SIZE); complex float* out3 = md_alloc(N, dims, CFL_SIZE); complex float* out4 = md_alloc(N, dims, CFL_SIZE); nlop_apply(zexp, N, dims, out1, N, dims, in1); nlop_apply(id, N, dims, out2, N, dims, in2); nlop_generic_apply_unchecked(comb, 4, (void*[]){ out3, out4, in1, in2 }); double err = md_znrmse(N, dims, out4, out2) + md_znrmse(N, dims, out3, out1); md_free(in1); md_free(in2); md_free(out1); md_free(out2); md_free(out3); md_free(out4); nlop_free(comb); nlop_free(id); nlop_free(zexp); UT_ASSERT((!safe_isnanf(err)) && (err < 1.E-2)); } UT_REGISTER_TEST(test_nlop_combine); static bool test_nlop_combine_der1(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; // FIXME: this test is broken struct nlop_s* zexp = nlop_zexp_create(N, dims); struct linop_s* lid = linop_identity_create(N, dims); struct nlop_s* id = nlop_from_linop(lid); linop_free(lid); struct nlop_s* comb = nlop_combine(zexp, id); random_application(zexp); complex float* in1 = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, in1); complex float* out1 = md_alloc(N, dims, CFL_SIZE); complex float* out2 = md_alloc(N, dims, CFL_SIZE); complex float* out3 = md_alloc(N, dims, CFL_SIZE); complex float* out4 = md_alloc(N, dims, CFL_SIZE); linop_forward(nlop_get_derivative(comb, 0, 1), N, dims, out1, N, dims, in1); if (0. != md_znorm(N, dims, out1)) return false; linop_forward(nlop_get_derivative(comb, 1, 0), N, dims, out1, N, dims, in1); if (0. != md_znorm(N, dims, out1)) return false; nlop_derivative(zexp, N, dims, out1, N, dims, in1); linop_forward(nlop_get_derivative(comb, 0, 0), N, dims, out2, N, dims, in1); nlop_derivative(id, N, dims, out3, N, dims, in1); linop_forward(nlop_get_derivative(comb, 1, 1), N, dims, out4, N, dims, in1); double err = md_znrmse(N, dims, out1, out2); md_free(in1); md_free(out1); md_free(out2); md_free(out3); md_free(out4); nlop_free(comb); nlop_free(id); nlop_free(zexp); return (0. == err); } UT_REGISTER_TEST(test_nlop_combine_der1); static bool test_nlop_comb_flat_der(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; struct nlop_s* zexp1 = nlop_zexp_create(N, dims); struct nlop_s* zexp2 = nlop_zexp_create(N, dims); random_application(zexp1); random_application(zexp2); struct nlop_s* comb = nlop_combine(zexp1, zexp2); struct nlop_s* flat = nlop_flatten(comb); auto iov = nlop_domain(flat); complex float* in = md_alloc(iov->N, iov->dims, iov->size); complex float* dst2 = md_alloc(iov->N, iov->dims, iov->size); complex float* dst = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, in); nlop_derivative(zexp1, N, dims, dst, N, dims, in); nlop_derivative(flat, iov->N, iov->dims, dst2, iov->N, iov->dims, in); double err = md_znrmse(N, dims, dst2, dst); md_free(in); md_free(dst); md_free(dst2); nlop_free(flat); nlop_free(comb); nlop_free(zexp1); nlop_free(zexp2); UT_ASSERT((!safe_isnanf(err)) && (err < 1.E-2)); } UT_REGISTER_TEST(test_nlop_comb_flat_der); static bool test_nlop_combine_derivative(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; // FIXME: this test is broken struct nlop_s* zexp1 = nlop_zexp_create(N, dims); struct nlop_s* zexp2 = nlop_zexp_create(N, dims); struct nlop_s* comb = nlop_combine(zexp1, zexp2); struct nlop_s* flat = nlop_flatten(comb); double err = nlop_test_derivative(flat); nlop_free(flat); nlop_free(comb); nlop_free(zexp1); nlop_free(zexp2); UT_ASSERT((!safe_isnanf(err)) && (err < 2.E-2)); } UT_REGISTER_TEST(test_nlop_combine_derivative); static bool test_nlop_link(void) { enum { N = 3 }; long dims[N] = { 10, 7, 3 }; complex float val = 2.; struct linop_s* cdiag = linop_cdiag_create(N, dims, 0, &val); struct nlop_s* diag = nlop_from_linop(cdiag); linop_free(cdiag); struct nlop_s* zexp = nlop_zexp_create(N, dims); struct nlop_s* zexp2 = nlop_chain(zexp, diag); struct nlop_s* zexp3 = nlop_combine(diag, zexp); struct nlop_s* zexp4 = nlop_link(zexp3, 1, 0); complex float* in = md_alloc(N, dims, CFL_SIZE); complex float* dst1 = md_alloc(N, dims, CFL_SIZE); complex float* dst2 = md_alloc(N, dims, CFL_SIZE); md_gaussian_rand(N, dims, in); nlop_apply(zexp2, N, dims, dst1, N, dims, in); nlop_apply(zexp4, N, dims, dst2, N, dims, in); double err = md_znrmse(N, dims, dst2, dst1); md_free(in); md_free(dst1); md_free(dst2); nlop_free(zexp4); nlop_free(zexp3); nlop_free(zexp2); nlop_free(zexp); nlop_free(diag); UT_ASSERT(err < 1.E-6); } UT_REGISTER_TEST(test_nlop_link); bart-0.5.00/utests/test_nufft.c000066400000000000000000000117301353046746100164130ustar00rootroot00000000000000/* Copyright 2017-2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017-2018 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/rand.h" #include "linops/linop.h" #include "linops/lintest.h" #include "noncart/nufft.h" #include "misc/misc.h" #include "misc/debug.h" #include "utest.h" enum { N = 8 }; static const long ksp_dims[N] = { 1, 5, 1, 1, 1, 1, 1, 1 }; static const long cim_dims[N] = { 8, 8, 1, 1, 1, 1, 1, 1 }; static const long trj_dims[N] = { 3, 5, 1, 1, 1, 1, 1, 1 }; static const complex float traj[5][3] = { { 0., 0. , 0. }, { 1., 0. , 0. }, { 0., 1. , 0. }, { -1., 0., 0. }, { 0., -1., 0. }, }; static struct linop_s* create_nufft(bool toeplitz, bool use_weights) { const complex float weights[5] = { 0.5, 0.5, 0.5, 0.5, 0.5 }; struct nufft_conf_s conf = nufft_conf_defaults; conf.toeplitz = toeplitz; return nufft_create(N, ksp_dims, cim_dims, trj_dims, &traj[0][0], use_weights ? weights : NULL, conf); } static const long ci2_dims[N] = { 8, 8, 1, 1, 1, 1, 2, 1 }; static const long ks2_dims[N] = { 1, 5, 1, 1, 1, 1, 2, 1 }; static const long tr2_dims[N] = { 3, 5, 1, 1, 1, 1, 1, 1 }; static const long bas_dims[N] = { 1, 1, 1, 1, 1, 3, 2, 1 }; static const long wg2_dims[N] = { 1, 5, 1, 1, 1, 3, 1, 1 }; static struct linop_s* create_nufft2(bool toeplitz) { const complex float weights[15] = { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, }; const complex float basis[6] = { 1., 0., 1., 0., 1., 0., }; struct nufft_conf_s conf = nufft_conf_defaults; conf.toeplitz = toeplitz; return nufft_create2(N, ks2_dims, ci2_dims, tr2_dims, &traj[0][0], wg2_dims, weights, bas_dims, basis, conf); } static bool test_nufft_forward(void) { const complex float src[] = { 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., }; struct linop_s* op = create_nufft(false, false); complex float dst[5]; linop_forward(op, N, ksp_dims, dst, N, cim_dims, src); linop_free(op); return (cabsf(dst[0] - 8.f) < 0.02); // ! } static bool test_nufft_adjoint(void) { struct linop_s* op = create_nufft(false, false); float diff = linop_test_adjoint(op); debug_printf(DP_DEBUG1, "adjoint diff: %f\n", diff); bool ret = (diff < 1.E-6f); linop_free(op); return ret; } static bool test_nufft_normal(void) { struct linop_s* op = create_nufft(false, false); float nrmse = linop_test_normal(op); debug_printf(DP_DEBUG1, "normal nrmse: %f\n", nrmse); bool ret = (nrmse < 1.E-7f); linop_free(op); return ret; } static bool test_nufft_toeplitz(bool use_weights) { complex float src[64]; complex float dst1[64] = { 0 }; complex float dst2[64] = { 0 }; md_gaussian_rand(N, cim_dims, src); struct linop_s* op1 = create_nufft(false, use_weights); linop_normal(op1, N, cim_dims, dst1, src); linop_free(op1); struct linop_s* op2 = create_nufft(true, use_weights); linop_normal(op2, N, cim_dims, dst2, src); linop_free(op2); return md_znrmse(N, cim_dims, dst1, dst2) < 0.01; } static bool test_nufft_toeplitz_noweights(void) { return test_nufft_toeplitz(false); } static bool test_nufft_toeplitz_weights(void) { return test_nufft_toeplitz(true); } static bool test_nufft_basis_adjoint(void) { struct linop_s* op = create_nufft2(false); float diff = linop_test_adjoint(op); debug_printf(DP_DEBUG1, "adjoint diff: %f\n", diff); bool ret = (diff < 1.E-6f); linop_free(op); return ret; } static bool test_nufft_basis_normal(void) { struct linop_s* op = create_nufft2(false); float nrmse = linop_test_normal(op); debug_printf(DP_DEBUG1, "normal nrmse: %f\n", nrmse); bool ret = (nrmse < 1.E-7f); linop_free(op); return ret; } static bool test_nufft_basis_toeplitz(void) { complex float src[128]; complex float dst1[128]; complex float dst2[128]; assert(128 == md_calc_size(N, ci2_dims)); md_gaussian_rand(N, ci2_dims, src); struct linop_s* op1 = create_nufft2(false); linop_normal(op1, N, ci2_dims, dst1, src); linop_free(op1); struct linop_s* op2 = create_nufft2(true); linop_normal(op2, N, ci2_dims, dst2, src); linop_free(op2); complex float sc = md_zscalar(N, ci2_dims, dst2, dst1); float n = md_znorm(N, ci2_dims, dst1); md_zsmul(N, ci2_dims, dst1, dst1, sc / (n * n)); return md_znrmse(N, ci2_dims, dst1, dst2) < 1.E-4; } UT_REGISTER_TEST(test_nufft_forward); UT_REGISTER_TEST(test_nufft_adjoint); UT_REGISTER_TEST(test_nufft_normal); UT_REGISTER_TEST(test_nufft_toeplitz_weights); UT_REGISTER_TEST(test_nufft_toeplitz_noweights); UT_REGISTER_TEST(test_nufft_basis_adjoint); UT_REGISTER_TEST(test_nufft_basis_normal); UT_REGISTER_TEST(test_nufft_basis_toeplitz); bart-0.5.00/utests/test_ode_bloch.c000066400000000000000000000147271353046746100172200ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include "num/ode.h" #include "simu/bloch.h" #include "utest.h" #if 0 static void lorenz(float out[3], const float in[3], float sigma, float rho, float beta) { out[0] = sigma * (in[1] - in[0]); out[1] = in[0] * (rho - in[2]) - in[1]; out[2] = in[0] * in[1] - beta * in[2]; } static void lorenz_fun(void* data, float* out, float t, const float* in) { (void)data; (void)t; lorenz(out, in, 10., 28., 8. / 3.); } #endif struct bloch_s { float r1; float r2; float gb[3]; }; static void bloch_fun(void* _data, float* out, float t, const float* in) { struct bloch_s* data = _data; (void)t; bloch_ode(out, in, data->r1, data->r2, data->gb); } static void bloch_pdy2(void* _data, float* out, float t, const float* in) { struct bloch_s* data = _data; (void)t; bloch_pdy((float(*)[3])out, in, data->r1, data->r2, data->gb); } static void bloch_pdp2(void* _data, float* out, float t, const float* in) { struct bloch_s* data = _data; (void)t; bloch_pdp((float(*)[3])out, in, data->r1, data->r2, data->gb); } static bool test_ode_bloch(void) { struct bloch_s data = { 1. / WATER_T1, 1. / WATER_T2, { 0., 0., GAMMA_H1 * SKYRA_GRADIENT * 0.0001 } }; float x[3] = { 1., 0., 0. }; float x0[3] = { 1., 0., 0. }; float x2[3]; float h = 0.1; float tol = 0.000001; float end = 0.2; ode_interval(h, tol, 3, x, 0., end, &data, bloch_fun); bloch_relaxation(x2, end, x0, data.r1, data.r2, data.gb); float err2 = 0.; for (int i = 0; i < 3; i++) err2 += powf(x[i] - x2[i], 2.); return (err2 < 1.E-7); } UT_REGISTER_TEST(test_ode_bloch); static bool test_bloch_matrix(void) { struct bloch_s data = { 1. / WATER_T1, 1. / WATER_T2, { 0., 0., GAMMA_H1 * SKYRA_GRADIENT * 0.0001 } }; float m[4][4]; bloch_matrix_ode(m, data.r1, data.r2, data.gb); float m0[4] = { 0.1, 0.2, 0.3, 1. }; float out[3]; bloch_ode(out, m0, data.r1, data.r2, data.gb); float out2[4]; for (unsigned int i = 0; i < 4; i++) { out2[i] = 0.; for (unsigned int j = 0; j < 4; j++) out2[i] += m[i][j] * m0[j]; } return (0. == out[0] - out2[0]) && (0. == out[1] - out2[1]) && (0. == out[2] - out2[2]) && (0. == out2[3]); } UT_REGISTER_TEST(test_bloch_matrix); static bool test_ode_matrix_bloch(void) { struct bloch_s data = { 1. / WATER_T1, 1. / WATER_T2, { 0., 0., GAMMA_H1 * SKYRA_GRADIENT * 0.0001 } }; float x[4] = { 1., 0., 0., 1. }; float x0[3] = { 1., 0., 0. }; float x2[3]; float h = 0.1; float tol = 0.000001; float end = 0.2; float m[4][4]; bloch_matrix_ode(m, data.r1, data.r2, data.gb); ode_matrix_interval(h, tol, 4, x, 0., end, m); bloch_relaxation(x2, end, x0, data.r1, data.r2, data.gb); float err2 = 0.; for (int i = 0; i < 3; i++) err2 += powf(x[i] - x2[i], 2.); return (err2 < 1.E-6); } UT_REGISTER_TEST(test_ode_matrix_bloch); struct sa_data_s { int N; float* r; }; static void sa_fun(void* _data, float* out, float t) { struct sa_data_s* data = _data; for (int i = 0; i < data->N; i++) out[i] = expf(data->r[i] * t); } static void sa_der(void* _data, float* out, float t, const float* in) { struct sa_data_s* data = _data; (void)t; for (int i = 0; i < data->N; i++) out[i] = data->r[i] * in[i]; } static void sa_pdy(void* _data, float* out, float t, const float* in) { struct sa_data_s* data = _data; (void)t; (void)in; for (int i = 0; i < data->N; i++) for (int j = 0; j < data->N; j++) out[i * data->N + j] = (i == j) ? data->r[i] : 0.; } static void sa_pdp(void* _data, float* out, float t, const float* in) { struct sa_data_s* data = _data; (void)t; for (int i = 0; i < data->N; i++) for (int j = 0; j < data->N; j++) out[i * data->N + j] = (i == j) ? in[i] : 0.; } static bool test_ode_sa(void) { float h = 0.1; float tol = 0.000001; float end = 0.2; struct sa_data_s data = { 1, (float[1]){ -WATER_T2 } }; float xp[2][1] = { { 1. }, { 0. } }; ode_direct_sa(h, tol, 1, 1, xp, 0., end, &data, sa_der, sa_pdy, sa_pdp); float x[1] = { 1. }; sa_fun(&data, x, end); if (fabsf(x[0] - xp[0][0]) > 1.E-30) return false; float y[1]; float q = 0.0001; data.r[0] += q; sa_fun(&data, y, end); float df = y[0] - x[0]; float err = fabsf(df - xp[1][0] * q); return err < 1.E-9; } UT_REGISTER_TEST(test_ode_sa); static bool test_ode_sa2(void) { float h = 0.1; float tol = 0.000001; float end = 0.2; int N = 10; float r[N]; for (int i = 0; i < N; i++) r[i] = -WATER_T2 / (1 + i); struct sa_data_s data = { N, r }; float xp[N + 1][N]; for (int i = 0; i < N; i++) { xp[0][i] = 1.; for (int j = 0; j < N; j++) xp[1 + j][i] = 0; } ode_direct_sa(h, tol, N, N, xp, 0., end, &data, sa_der, sa_pdy, sa_pdp); float x[N]; sa_fun(&data, x, end); for (int i = 0; i < N; i++) { float err = fabsf(x[i] - xp[0][i]); if (err > 1.E-6) return false; } float y[N]; float q = 0.0001; for (int j = 0; j < N; j++) { data.r[j] += q; sa_fun(&data, y, end); data.r[j] -= q; for (int i = 0; i < N; i++) { float df = y[i] - x[i]; float sa = xp[1 + j][i] * q; float err = fabsf(df - sa); // printf("%d %d-%e-%e-%e\n", j, i, err, df, sa); if (err > 1.E-7) return false; } } return true; } UT_REGISTER_TEST(test_ode_sa2); static bool test_ode_sa_bloch(void) { struct bloch_s data = { 1. / WATER_T1, 1. / WATER_T2, { 0., 0., GAMMA_H1 * SKYRA_GRADIENT * 0.0001 } }; float xp[3][3] = { { 1., 0., 0. }, { 0. }, { 0. } }; float x0[3] = { 1., 0., 0. }; float x2[3]; float x2r1[3]; float x2r2[3]; float h = 0.1; float tol = 0.000001; float end = 0.2; float q = 1.E-3; ode_direct_sa(h, tol, 3, 2, xp, 0., end, &data, bloch_fun, bloch_pdy2, bloch_pdp2); bloch_relaxation(x2, end, x0, data.r1, data.r2, data.gb); bloch_relaxation(x2r1, end, x0, data.r1 + q, data.r2, data.gb); bloch_relaxation(x2r2, end, x0, data.r1, data.r2 + q, data.gb); float err2 = 0.; for (int i = 0; i < 3; i++) err2 += powf(xp[0][i] - x2[i], 2.); if (err2 > 1.E-7) return false; for (int i = 0; i < 3; i++) err2 += powf(xp[0][i] - x2[i], 2.); for (int i = 0; i < 3; i++) { float err = fabsf(q * xp[1][i] - (x2r1[i] - x2[i])); if (err > 1.E-7) return false; } for (int i = 0; i < 3; i++) { float err = fabsf(q * xp[2][i] - (x2r2[i] - x2[i])); if (err > 1.E-7) return false; } return true; } UT_REGISTER_TEST(test_ode_sa_bloch); bart-0.5.00/utests/test_ops.c000066400000000000000000000047611353046746100161000ustar00rootroot00000000000000/* Copyright 2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2019 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "num/ops.h" #include "misc/misc.h" #include "misc/debug.h" #include "utest.h" static bool test_op_stack(void) { enum { N = 3 }; long dims[N] = { 8, 4, 1 }; long dims2[N] = { 8, 4, 2 }; const auto a = operator_identity_create(N, dims); const auto b = operator_zero_create(N, dims); const auto c = operator_null_create(N, dims); const auto d = operator_combi_create(2, MAKE_ARRAY(OP_PASS(b), OP_PASS(c))); const auto e = operator_stack(2, 2, OP_PASS(a), OP_PASS(d)); complex float* in = md_alloc(N, dims2, CFL_SIZE); complex float* out = md_alloc(N, dims2, CFL_SIZE); md_zfill(N, dims2, in, 1.); md_zfill(N, dims2, out, 100.); operator_apply(e, N, dims2, out, N, dims2, in); double err = fabsf(md_znorm(N, dims2, in) - sqrtf(2.) * md_znorm(N, dims2, out)); operator_free(e); md_free(in); md_free(out); return (err < UT_TOL); } UT_REGISTER_TEST(test_op_stack); static bool test_op_extract(void) { enum { N = 3 }; long dims[N] = { 8, 4, 1 }; long dims2[N] = { 8, 4, 2 }; const auto a = operator_identity_create(N, dims); const auto b = operator_zero_create(N, dims); const auto c = operator_null_create(N, dims); const auto d = operator_combi_create(2, MAKE_ARRAY(OP_PASS(b), OP_PASS(c))); const auto e = operator_extract_create(OP_PASS(a), 0, N, dims2, (long[]){ 0, 0, 0 }); const auto f = operator_extract_create(OP_PASS(e), 1, N, dims2, (long[]){ 0, 0, 0 }); const auto g = operator_extract_create(OP_PASS(d), 0, N, dims2, (long[]){ 0, 0, 1 }); const auto h = operator_extract_create(OP_PASS(g), 1, N, dims2, (long[]){ 0, 0, 1 }); const auto i = operator_combi_create(2, MAKE_ARRAY(OP_PASS(f), OP_PASS(h))); const auto j = operator_dup_create(OP_PASS(i), 0, 2); const auto k = operator_dup_create(OP_PASS(j), 1, 2); complex float* in = md_alloc(N, dims2, CFL_SIZE); complex float* out = md_alloc(N, dims2, CFL_SIZE); md_zfill(N, dims2, in, 1.); md_zfill(N, dims2, out, 100.); operator_apply(k, N, dims2, out, N, dims2, in); double err = fabsf(md_znorm(N, dims2, in) - sqrtf(2.) * md_znorm(N, dims2, out)); operator_free(k); md_free(in); md_free(out); return (err < UT_TOL); } UT_REGISTER_TEST(test_op_extract); bart-0.5.00/utests/test_ops_p.c000066400000000000000000000032471353046746100164150ustar00rootroot00000000000000/* Copyright 2019. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2019 Martin Uecker */ #include #include #include "num/multind.h" #include "num/flpmath.h" #include "num/iovec.h" #include "num/ops_p.h" #include "misc/misc.h" #include "misc/debug.h" #include "misc/types.h" #include "utest.h" static bool test_op_p_scale(void) { enum { N = 3 }; long dims[N] = { 8, 4, 1 }; complex float* in = md_alloc(N, dims, CFL_SIZE); complex float* out = md_alloc(N, dims, CFL_SIZE); md_zfill(N, dims, in, 1.); md_zfill(N, dims, out, 100.); const struct operator_p_s* a = operator_p_scale(N, dims); operator_p_apply(a, 2., N, dims, out, N, dims, in); operator_p_free(a); md_zfill(N, dims, in, 2.); float err = md_znrmse(N, dims, out, in); md_free(in); md_free(out); return (err < UT_TOL); } UT_REGISTER_TEST(test_op_p_scale); static bool test_op_p_stack(void) { enum { N = 3 }; long dims[N] = { 8, 4, 1 }; long dims2[N] = { 8, 4, 2 }; auto a = operator_p_scale(N, dims); auto a2 = operator_p_scale(N, dims); auto b = operator_p_stack(2, 2, a, a2); operator_p_free(a); operator_p_free(a2); complex float* in = md_alloc(N, dims2, CFL_SIZE); complex float* out = md_alloc(N, dims2, CFL_SIZE); md_zfill(N, dims2, in, 1.); md_zfill(N, dims2, out, 100.); operator_p_apply(b, 2., N, dims2, out, N, dims2, in); operator_p_free(b); md_zfill(N, dims2, in, 2.); float err = md_znrmse(N, dims2, out, in); md_free(in); md_free(out); return (err < UT_TOL); } UT_REGISTER_TEST(test_op_p_stack); bart-0.5.00/utests/test_pattern.c000066400000000000000000000030051353046746100167420ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jonathan Tamir */ #include #include #include "num/flpmath.h" #include "num/multind.h" #include "misc/debug.h" #include "misc/misc.h" #include "misc/mri.h" #include "utest.h" static bool test_pattern_flags(unsigned int D, const long dims[D], unsigned int flags, const complex float* in, const complex float* ref) { long odims[D]; md_select_dims(D, ~flags, odims, dims); complex float* out = md_alloc(D, odims, CFL_SIZE); estimate_pattern(D, dims, flags, out, in); bool ret = (md_znrmse(D, odims, ref, out) < UT_TOL); md_free(out); return ret; } static bool test_pattern(void) { const complex float in[1][5][3] = { { { 3., 0., 0. }, { 0., 2., 0. }, { .2, 0., 0. }, { 0., 0., 0. }, { 0., 2., 0. }, } }; const complex float ref0[1][5][3] = { { { 1., 0., 0. }, { 0., 1., 0. }, { 1., 0., 0. }, { 0., 0., 0. }, { 0., 1., 0. }, } }; const complex float ref2[1][1][3] = { { { 1., 1., 0. }, } }; const complex float ref3[1][1][1] = { { { 1. }, } }; long idims[3] = { 3, 5, 1 }; return (test_pattern_flags(3, idims, 0, &in[0][0][0], &ref0[0][0][0]) && test_pattern_flags(3, idims, 2, &in[0][0][0], &ref2[0][0][0]) && test_pattern_flags(3, idims, 3, &in[0][0][0], &ref3[0][0][0])); } UT_REGISTER_TEST(test_pattern); bart-0.5.00/utests/test_polynom.c000066400000000000000000000065111353046746100167670ustar00rootroot00000000000000 #include "misc/misc.h" #include "num/polynom.h" #include "utest.h" static bool test_polynom_eval(void) { const complex double coeff[3] = { 1., 0., 1. }; bool ok = true; ok &= (1. == polynom_eval(0., 2, coeff)); ok &= (2. == polynom_eval(1., 2, coeff)); ok &= (2. == polynom_eval(-1., 2, coeff)); return ok; } UT_REGISTER_TEST(test_polynom_eval); static bool array_eq(int N, const complex double c1[N], const complex double c2[N], double eps) { return (0 == N) ? true : ((cabs(c1[0] - c2[0]) <= eps) && array_eq(N - 1, c1 + 1, c2 + 1, eps)); } static bool test_polynom_derivative(void) { const complex double coeff[3] = { 1., 0., 1. }; complex double coeff2[2]; polynom_derivative(2, coeff2, coeff); return array_eq(2, coeff2, (const complex double[]){ 0., 2. }, 0.); } UT_REGISTER_TEST(test_polynom_derivative); static bool test_polynom_integral(void) { const complex double coeff[3] = { 1., 0., 1. }; complex double coeff2[2]; complex double coeff3[3]; polynom_derivative(2, coeff2, coeff); polynom_integral(1, coeff3, coeff2); return ((0. == coeff3[1]) && (1. == coeff3[2])); } UT_REGISTER_TEST(test_polynom_integral); static bool test_polynom_integrate(void) { const complex double coeff2[2] = { 0., 1. }; return (0.5 == polynom_integrate(0., 1., 1, coeff2)); } UT_REGISTER_TEST(test_polynom_integrate); static bool test_polynom_from_roots1(void) { const complex double roots[2] = { 1., -2.i }; // (x - 1.) * (x + 2.i) == x^2 + (-1 + 2.i) x -2i. const complex double coeff0[3] = { -2.i, -1. + 2.i, 1. }; complex double coeff[3]; polynom_from_roots(2, coeff, roots); return array_eq(3, coeff0, coeff, 0.); } UT_REGISTER_TEST(test_polynom_from_roots1); static bool test_polynom_from_roots(void) { const complex double roots[3] = { 1., 2., 3. }; complex double coeff[4]; polynom_from_roots(3, coeff, roots); bool ok = true; for (unsigned int i = 0; i < ARRAY_SIZE(roots); i++) ok &= (0. == polynom_eval(roots[i], 3, coeff)); complex double prod = 1.; for (unsigned int i = 0; i < ARRAY_SIZE(roots); i++) prod *= -roots[i]; ok &= (prod == polynom_eval(0., 3, coeff)); return ok; } UT_REGISTER_TEST(test_polynom_from_roots); static bool test_polynom_scale(void) { const complex double coeff[3] = { 1., 0., 1. }; complex double coeff2[3]; polynom_scale(2, coeff2, 2., coeff); return (5. == polynom_eval(1., 2, coeff2)); } UT_REGISTER_TEST(test_polynom_scale); static bool test_polynom_shift(void) { const complex double coeff[3] = { 1., 0., 1. }; // 1. + (x + 1)^2 = 2 + 2 * x + x^2 complex double coeff2[3]; polynom_shift(2, coeff2, 1., coeff); return array_eq(3, coeff2, (const complex double[]){ 2., 2., 1. }, 0.); } UT_REGISTER_TEST(test_polynom_shift); static bool test_quadratic_formula(void) { const complex double roots[2] = { 1., -2.i }; // (x - 1.) * (x + 2.i) == x^2 + (-1 + 2.i) x -2i. complex double coeff[3] = { -2.i, -1. + 2.i, 1. }; complex double r2[2]; quadratic_formula(r2, coeff); return array_eq(2, r2, roots, 1.e-15); } UT_REGISTER_TEST(test_quadratic_formula); static bool test_cubic_formula(void) { const complex double roots[3] = { 1., 0.5, -2.i }; complex double coeff[4]; polynom_from_roots(3, coeff, roots); complex double r2[3]; cubic_formula(r2, coeff); return array_eq(3, r2, roots, 1.E-15); } UT_REGISTER_TEST(test_cubic_formula); bart-0.5.00/utests/test_splines.c000066400000000000000000000142401353046746100167450ustar00rootroot00000000000000/* Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Martin Uecker */ #include #include #include "num/splines.h" #include "utest.h" static const double coords[5] = { 0., 1., 0.5, 1., 0.5 }; static bool test_bezier_curve(void) { bool ret = true; ret = ret && (coords[0] == bezier_curve(0., 4, coords)); ret = ret && (coords[4] == bezier_curve(1., 4, coords)); return ret; } UT_REGISTER_TEST(test_bezier_curve); static bool test_bezier_increase_degree(void) { double coords2[6]; bezier_increase_degree(4, coords2, coords); double err = 0.; for (double x = 0.; x < 1.; x += 0.01) { double a = bezier_curve(x, 4, coords); double b = bezier_curve(x, 5, coords2); err += pow(a - b, 2); } return (err < 1.E-28); } UT_REGISTER_TEST(test_bezier_increase_degree); static bool test_bezier_split(void) { double coords[5] = { 0., 1., 0.5, 1., 0.5 }; double coordsA[5]; double coordsB[5]; bezier_split(0.5, 4, coordsA, coordsB, coords); double err = 0.; for (double x = 0.; x < 1.; x += 0.01) { double a = bezier_curve(x, 4, coords); double b = (x <= 0.5) ? bezier_curve(2. * x, 4, coordsA) : bezier_curve(2. * (x - 0.5), 4, coordsB); err += pow(a - b, 2); } return (err < 1.E-28); } UT_REGISTER_TEST(test_bezier_split); static bool test_cspline(void) { const double coeff[4] = { 0., 1., 1., 1. }; bool ok = true; for (double x = 0.; x < 1.; x += 0.1) ok &= (fabs(x - cspline(x, coeff)) < 1.E-15); return ok; } UT_REGISTER_TEST(test_cspline); static bool test_bspline(void) { const double knots[11] = { 0., 0.0, 0.0, 0., 0.25, 0.5, 0.75, 1., 1., 1., 1. }; bool ok = true; for (int i = 0; i < 7; i++) { double coord[7] = { 0., 0., 0., 0., 0., 0., 0. }; coord[i] = 1.; double err = 0.; for (double x = 0.; x <= 1.; x += 0.01) { double a = bspline(10, i, 3, knots, x); double b = bspline_curve(10, 3, knots, coord, x); err += pow(a - b, 2); } ok &= (err < 1.E-28); } return ok; } UT_REGISTER_TEST(test_bspline); static bool test_bspline_knot_insert(void) { const double knots[11] = { 0., 0.0, 0.0, 0., 0.25, 0.5, 0.75, 1., 1., 1., 1. }; double coord[7] = { 0., 0., 0.75, 0.5, 0.25, 0., 0 }; double knots2[12]; double coord2[8]; bspline_knot_insert(0.6, 10, 3, knots2, coord2, knots, coord); double err = 0.; for (double x = 0.; x < 1.; x += 0.01) { double a = bspline_curve(10, 3, knots, coord, x); double b = bspline_curve(11, 3, knots2, coord2, x); err += pow(a - b, 2); } return (err < 1.E-28); } UT_REGISTER_TEST(test_bspline_knot_insert); static bool test_bspline_derivative(void) { const double knots[11] = { 0., 0.0, 0.0, 0., 0.25, 0.5, 0.75, 1., 1., 1., 1. }; bool ok = true; for (int i = 0; i < 7; i++) { double coord[7] = { 0., 0., 0., 0., 0., 0., 0. }; coord[i] = 1.; double err = 0.; for (double x = 0.; x <= 1.; x += 0.01) { double a = bspline_derivative(10, i, 3, knots, x); double b = bspline_curve_derivative(1, 10, 3, knots, coord, x); err += pow(a - b, 2); } ok &= (err < 1.E-1); } return ok; } UT_REGISTER_TEST(test_bspline_derivative); static bool test_bspline_zero(void) { const double knots[11] = { 0., 0.0, 0.0, 0., 0.25, 0.5, 0.75, 1., 1., 1., 1. }; const double z0[7] = { 0., 0., 0.75, 0.5, 0.25, 0., 0 }; bool ok = true; for (int i = 2; i < 5; i++) { // FIXME double coord[7] = { 0., 0., 0., 0., 0., 0., 0. }; coord[i] = 1.; double k2[10] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // FIXME: this and next line's inits may hide bug (crash with clang) double c2[7] = { 0., 0., 0., 0., 0., 0., 0. }; // (Also length must be longer than in prototype) bspline_coeff_derivative_n(1, 10, 3, k2, c2, knots, coord); double z = bspline_curve_zero(8, 2, k2, c2); ok &= (fabs(z - z0[i]) < 1.E-5); } return ok; } UT_REGISTER_TEST(test_bspline_zero); static bool test_nurbs(void) { const double knots[11] = { 0., 0.0, 0.0, 0., 0.25, 0.5, 0.75, 1., 1., 1., 1. }; bool ok = true; for (int i = 0; i < 7; i++) { double coord[7] = { 0., 0., 0., 0., 0., 0., 0. }; double weights[7] = { 1., 1., 1., 1., 1., 1., 1. }; coord[i] = 1.; double err = 0.; for (double x = 0.; x <= 1.; x += 0.01) { double a = nurbs(10, 3, knots, coord, weights, x); double b = bspline_curve(10, 3, knots, coord, x); double c = bspline_curve(10, 3, knots, weights, x); err += pow(a - b / c, 2); } ok &= (err < 1.E-28); } return ok; } UT_REGISTER_TEST(test_nurbs); static bool test_nurbs_arc(void) { const double knots[6] = { 0., 0., 0., 1., 1., 1. }; double coordx[3] = { 0., 1., 1. }; double coordy[3] = { 1., 1., 0. }; double weights[3] = { sqrt(2.), 1., sqrt(2.) }; bool ok = true; for (double t = 0.; t <= 1.; t += 0.01) { double x = nurbs(5, 2, knots, coordx, weights, t); double y = nurbs(5, 2, knots, coordy, weights, t); ok &= fabs(pow(x, 2.) + pow(y, 2.) - 1.) < 1.E-15; } return ok; } UT_REGISTER_TEST(test_nurbs_arc); static bool test_nurbs_circle(void) { const double knots[10] = { 0., 0., 0., 1., 1., 2., 2., 3., 3., 3. }; double coordx[7] = { cos(0. * 2. * M_PI / 3.) + cos(1. * 2. * M_PI / 3.), cos(1. * 2. * M_PI / 3.) * 2., cos(1. * 2. * M_PI / 3.) + cos(2. * 2. * M_PI / 3.), cos(2. * 2. * M_PI / 3.) * 2., cos(2. * 2. * M_PI / 3.) + cos(3. * 2. * M_PI / 3.), cos(3. * 2. * M_PI / 3.) * 2., cos(3. * 2. * M_PI / 3.) + cos(1. * 2. * M_PI / 3.), }; double coordy[7] = { sin(0. * 2. * M_PI / 3.) + sin(1. * 2. * M_PI / 3.), sin(1. * 2. * M_PI / 3.) * 2., sin(1. * 2. * M_PI / 3.) + sin(2. * 2. * M_PI / 3.), sin(2. * 2. * M_PI / 3.) * 2., sin(2. * 2. * M_PI / 3.) + sin(3. * 2. * M_PI / 3.), sin(3. * 2. * M_PI / 3.) * 2., sin(3. * 2. * M_PI / 3.) + sin(1. * 2. * M_PI / 3.), }; double weights[7] = { 1., 0.5, 1., 0.5, 1., 0.5, 1. }; bool ok = true; for (double t = 0.; t <= 3.; t += 0.01) { double x = nurbs(9, 2, knots, coordx, weights, t); double y = nurbs(9, 2, knots, coordy, weights, t); ok &= fabs(pow(x, 2.) + pow(y, 2.) - 1.) < 1.E-15; } return ok; } UT_REGISTER_TEST(test_nurbs_circle); bart-0.5.00/utests/test_types.c000066400000000000000000000020131353046746100164270ustar00rootroot00000000000000/* Copyright 2018. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2018 Martin Uecker */ #include "misc/types.h" #include "utest.h" typedef struct superclass_s { TYPEID* TYPEID; } superclass; struct class1 { INTERFACE(superclass); }; DEF_TYPEID(class1); static bool test_cast_down_pos(void) { bool ok = true; PTR_ALLOC(struct class1, cp); SET_TYPEID(class1, cp); struct superclass_s* sp = CAST_UP(cp); if (cp != CAST_MAYBE(class1, sp)) ok = false; PTR_FREE(cp); return ok; } UT_REGISTER_TEST(test_cast_down_pos); struct class2 { INTERFACE(superclass); }; DEF_TYPEID(class2); static bool test_cast_down_neg(void) { bool ok = true; PTR_ALLOC(struct class2, cp); SET_TYPEID(class2, cp); struct superclass_s* sp = CAST_UP(cp); if (NULL != CAST_MAYBE(class1, sp)) ok = false; PTR_FREE(cp); return ok; } UT_REGISTER_TEST(test_cast_down_neg); bart-0.5.00/utests/test_window.c000066400000000000000000000041101353046746100165720ustar00rootroot00000000000000/* Copyright 2017. The Regents of the University of California. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2017 Jon Tamir */ #include #include "num/filter.h" #include "num/flpmath.h" #include "num/multind.h" #include "misc/misc.h" #include "utest.h" static bool test_window(unsigned int D, long dims[D], long flags, bool hamming, const complex float* ref) { complex float* in = md_alloc(3, dims, CFL_SIZE); md_zfill(3, dims, in, 1.); complex float* out = md_alloc(3, dims, CFL_SIZE); (hamming ? md_zhamming : md_zhann)(3, dims, flags, out, in); bool ret = (md_znrmse(3, dims, &ref[0], out) < UT_TOL); md_free(out); md_free(in); return ret; } static bool test_hamming(void) { // compare to Matlab: // >> z = permute(repmat(hamming(5)*hamming(4)', [1, 1, 2]), [3, 1, 2]); // >> z(:) const complex float ref[2 * 5 * 4] = { 0.0064, 0.0064, 0.0432, 0.0432, 0.0800, 0.0800, 0.0432, 0.0432, 0.0064, 0.0064, 0.0616, 0.0616, 0.4158, 0.4158, 0.7700, 0.7700, 0.4158, 0.4158, 0.0616, 0.0616, 0.0616, 0.0616, 0.4158, 0.4158, 0.7700, 0.7700, 0.4158, 0.4158, 0.0616, 0.0616, 0.0064, 0.0064, 0.0432, 0.0432, 0.0800, 0.0800, 0.0432, 0.0432, 0.0064, 0.0064, }; long dims[3] = { 2, 5, 4 }; return test_window(3, dims, MD_BIT(1) | MD_BIT(2), true, ref); } UT_REGISTER_TEST(test_hamming); static bool test_hann(void) { // compare to Matlab: // >> z = permute(repmat(hann(4)*hann(5)', [1, 1, 2]), [1, 3, 2]); // >> z(:) const complex float ref[4 * 2 * 5] = { 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.3750, 0.3750, 0.0000, 0.0000, 0.3750, 0.3750, 0.0000, 0.0000, 0.7500, 0.7500, 0.0000, 0.0000, 0.7500, 0.7500, 0.0000, 0.0000, 0.3750, 0.3750, 0.0000, 0.0000, 0.3750, 0.3750, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, }; long dims[3] = { 4, 2, 5 }; return test_window(3, dims, MD_BIT(0) | MD_BIT(2), false, ref); } UT_REGISTER_TEST(test_hann); bart-0.5.00/utests/utest.c000066400000000000000000000024771353046746100154060ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jonathan Tamir * 2016 Martin Uecker */ #include #include "misc/debug.h" #include "misc/misc.h" #include "utest.h" #if 0 /* A linker script is used to assemble a list of all * registered unit tests and to set begin and end. */ extern ut_test_f* _utests_begin; extern ut_test_f* _utests_end; #else /* A shell script called by make is used to create * the list of registered unit tests in UTESTS. * This also works on MacOS X. */ extern ut_test_f UTESTS dummy; ut_test_f* ut_tests[] = { UTESTS }; #define _utests_begin (ut_tests[0]) #define _utests_end (ut_tests[ARRAY_SIZE(ut_tests)]) #endif int main(int argc, char* argv[]) { UNUSED(argc); int num_tests_run = 0; int num_tests_pass = 0; for (ut_test_f** ptr = &_utests_begin; ptr != &_utests_end; ptr++) UNUSED((num_tests_run++, (**ptr)()) && num_tests_pass++); bool good = (num_tests_pass == num_tests_run); debug_printf(good ? DP_INFO : DP_ERROR, "%20s: %2d/%2d passed.\n", argv[0], num_tests_pass, num_tests_run); exit(good ? 0 : 1); } bart-0.5.00/utests/utest.h000066400000000000000000000015721353046746100154060ustar00rootroot00000000000000/* Copyright 2016. The Regents of the University of California. * Copyright 2016. Martin Uecker. * All rights reserved. Use of this source code is governed by * a BSD-style license which can be found in the LICENSE file. * * Authors: * 2016 Jonathan Tamir * 2016 Martin Uecker */ #ifndef _UTEST_H #define _UTEST_H #include #include "misc/debug.h" #include "misc/misc.h" #define UT_ASSERT(test) \ return ((test) || (debug_printf(DP_ERROR, "%s:%d assertion `%s` failed.\n", __func__, __LINE__, #test), false)) #define UT_TOL 1E-6 typedef bool ut_test_f(void); #if 0 #define UT_REGISTER_TEST(x) \ ut_test_f* ptr_ ## x __attribute__((section(".utest"))) = &x; #else #define UT_REGISTER_TEST(x) \ extern bool call_ ## x(void); \ extern bool call_ ## x(void) { return x(); }; #endif #endif bart-0.5.00/utests/utests-collect.sh000077500000000000000000000001651353046746100173770ustar00rootroot00000000000000#!/bin/sh UTESTS=$(grep UT_REGISTER $1 | cut -f2 -d'(' | cut -f1 -d')') for i in $UTESTS; do echo "call_$i," done bart-0.5.00/utests/utests.ld000066400000000000000000000002121353046746100157270ustar00rootroot00000000000000 SECTIONS { . = ALIGN(8); .utests_array : { _utests_begin = .; KEEP( *(.utest)) _utests_end = .; } } INSERT AFTER .rodata; bart-0.5.00/version.txt000066400000000000000000000000101353046746100147520ustar00rootroot00000000000000v0.5.00