├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── bin └── readme.asc ├── conda-recipe └── lsdtopotools │ ├── build.sh │ └── meta.yaml ├── docker_files ├── lsdtt_alpine │ └── dockerfile ├── lsdtt_docs │ └── dockerfile └── lsdtt_pcl │ └── dockerfile ├── history.asc ├── lsdtt2_setup.sh ├── lsdtt2_terminal.sh ├── readme.asc ├── src ├── CMakeLists.txt ├── DevelopmentToReleaseAutomator.py ├── LSDAnalysisDriver.cpp ├── LSDAnalysisDriver.hpp ├── LSDBasin.cpp ├── LSDBasin.hpp ├── LSDCRNParameters.cpp ├── LSDCRNParameters.hpp ├── LSDCatchmentModel.cpp ├── LSDCatchmentModel.hpp ├── LSDChannel.cpp ├── LSDChannel.hpp ├── LSDChiNetwork.cpp ├── LSDChiNetwork.hpp ├── LSDChiTools.cpp ├── LSDChiTools.hpp ├── LSDCloudBase.cpp ├── LSDCloudBase.hpp ├── LSDCloudRaster.cpp ├── LSDCloudRaster.hpp ├── LSDCosmoData.cpp ├── LSDCosmoData.hpp ├── LSDCosmoRaster.cpp ├── LSDCosmoRaster.hpp ├── LSDFileTools.cpp ├── LSDFileTools.hpp ├── LSDFloodplain.cpp ├── LSDFloodplain.hpp ├── LSDFlowInfo.cpp ├── LSDFlowInfo.hpp ├── LSDGeometry.cpp ├── LSDGeometry.hpp ├── LSDGrainMatrix.cpp ├── LSDGrainMatrix.hpp ├── LSDHollow.cpp ├── LSDHollow.hpp ├── LSDIndexChannel.cpp ├── LSDIndexChannel.hpp ├── LSDIndexChannelTree.cpp ├── LSDIndexChannelTree.hpp ├── LSDIndexRaster.cpp ├── LSDIndexRaster.hpp ├── LSDJunctionNetwork.cpp ├── LSDJunctionNetwork.hpp ├── LSDLithoCube.cpp ├── LSDLithoCube.hpp ├── LSDMatrix.hpp ├── LSDModelDriver.cpp ├── LSDModelDriver.hpp ├── LSDMostLikelyPartitionsFinder.cpp ├── LSDMostLikelyPartitionsFinder.hpp ├── LSDNetCDFTools.cpp ├── LSDParameterParser.cpp ├── LSDParameterParser.hpp ├── LSDParticle.cpp ├── LSDParticle.hpp ├── LSDParticleColumn.cpp ├── LSDParticleColumn.hpp ├── LSDPorewaterColumn.cpp ├── LSDPorewaterColumn.hpp ├── LSDPorewaterParams.cpp ├── LSDPorewaterParams.hpp ├── LSDRainfallRunoff.cpp ├── LSDRainfallRunoff.hpp ├── LSDRaster.cpp ├── LSDRaster.hpp ├── LSDRasterAggregator.cpp ├── LSDRasterAggregator.hpp ├── LSDRasterInfo.cpp ├── LSDRasterInfo.hpp ├── LSDRasterMaker.cpp ├── LSDRasterMaker.hpp ├── LSDRasterModel.cpp ├── LSDRasterModel.hpp ├── LSDRasterSpectral.cpp ├── LSDRasterSpectral.hpp ├── LSDShapeTools.cpp ├── LSDShapeTools.hpp ├── LSDSoilHydroRaster.cpp ├── LSDSoilHydroRaster.hpp ├── LSDSpatialCSVReader.cpp ├── LSDSpatialCSVReader.hpp ├── LSDStatsTools.cpp ├── LSDStatsTools.hpp ├── LSDStrahlerLinks.cpp ├── LSDStrahlerLinks.hpp ├── LSDSwathProfile.cpp ├── LSDSwathProfile.hpp ├── LSDTerrace.cpp ├── LSDTerrace.hpp ├── TNT │ ├── jama_cholesky.h │ ├── jama_eig.h │ ├── jama_lu.h │ ├── jama_qr.h │ ├── jama_svd.h │ ├── tnt.h │ ├── tnt_array1d.h │ ├── tnt_array1d_utils.h │ ├── tnt_array2d.h │ ├── tnt_array2d_utils.h │ ├── tnt_array3d.h │ ├── tnt_array3d_utils.h │ ├── tnt_cmat.h │ ├── tnt_fortran_array1d.h │ ├── tnt_fortran_array1d_utils.h │ ├── tnt_fortran_array2d.h │ ├── tnt_fortran_array2d_utils.h │ ├── tnt_fortran_array3d.h │ ├── tnt_fortran_array3d_utils.h │ ├── tnt_i_refvec.h │ ├── tnt_math_utils.h │ ├── tnt_sparse_matrix_csr.h │ ├── tnt_stopwatch.h │ ├── tnt_subscript.h │ ├── tnt_vec.h │ └── tnt_version.h ├── build.sh ├── fftw-3.3.4 │ └── api │ │ └── fftw3.h └── lsdtt-drivers │ ├── lsdtt-basic-metrics.cpp │ ├── lsdtt-channel-extraction.cpp │ ├── lsdtt-chi-mapping.cpp │ ├── lsdtt-cosmo-tool.cpp │ ├── lsdtt-hillslope-channel-coupling.cpp │ ├── lsdtt-river-clusters.cpp │ └── lsdtt-valley-metrics.cpp └── tests ├── fixtures ├── coweeta.driver └── paths.json └── test_slope.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Declare files that will always have CRLF line endings on checkout. 5 | *.sln text eol=crlf 6 | 7 | # Denote all files that are truly binary and should not be modified. 8 | *.png binary 9 | *.jpg binary 10 | 11 | #sources 12 | *.c text 13 | *.cc text 14 | *.cxx text 15 | *.cpp text 16 | *.c++ text 17 | *.hpp text 18 | *.h text 19 | *.h++ text 20 | *.hh text 21 | 22 | # Compiled Object files 23 | *.slo binary 24 | *.lo binary 25 | *.o binary 26 | *.obj binary 27 | 28 | # Precompiled Headers 29 | *.gch binary 30 | *.pch binary 31 | 32 | # Compiled Dynamic libraries 33 | *.so binary 34 | *.dylib binary 35 | *.dll binary 36 | 37 | # Compiled Static libraries 38 | *.lai binary 39 | *.la binary 40 | *.a binary 41 | *.lib binary 42 | 43 | # Executables 44 | *.exe binary 45 | *.out binary 46 | *.app binary 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.out 3 | *.exe 4 | driver_functions_FJC/terraces/build/* 5 | driver_functions_FJC/swath_profiles/build/* 6 | driver_functions_Floodplains-Terraces/build/CMakeCache.txt 7 | driver_functions_Floodplains-Terraces/build/CMakeFiles/* 8 | driver_functions_Floodplains-Terraces/build/Makefile 9 | driver_functions_Floodplains-Terraces/build/cmake_install.cmake 10 | boost/* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: required 3 | language: 4 | - cpp 5 | compiler: 6 | - gcc 7 | before_install: 8 | - sudo apt-get install -y libfftw3-dev 9 | - cd ./src 10 | script: 11 | # Run your build commands next 12 | - sh build.sh 13 | 14 | -------------------------------------------------------------------------------- /bin/readme.asc: -------------------------------------------------------------------------------- 1 | = Instructions for running these scripts. 2 | 3 | You need to add this directory to your path if you want to run *LSDTopoTools* from the command line. 4 | 5 | You can https://stackoverflow.com/questions/14637979/how-to-permanently-set-path-on-linux-unix[edit your `.bashrc` file]. 6 | 7 | Or you can https://unix.stackexchange.com/questions/23426/how-to-alter-path-within-a-shell-script[spawn a new shell] with the correct paths. -------------------------------------------------------------------------------- /conda-recipe/lsdtopotools/build.sh: -------------------------------------------------------------------------------- 1 | export LDFLAGS="-Wl,-rpath,$PREFIX/lib -L$PREFIX/lib $LDFLAGS" 2 | 3 | cmake -DCMAKE_INSTALL_PREFIX=$PREFIX $SRC_DIR -DCMAKE_INSTALL_BINDIR=bin 4 | 5 | make 6 | make install 7 | -------------------------------------------------------------------------------- /conda-recipe/lsdtopotools/meta.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: lsdtopotools 3 | version: "0.1" 4 | 5 | source: 6 | path: ../.. 7 | # git_url: https://github.com/LSDtopotools/LSDTT_public.git 8 | # git_rev: master 9 | 10 | build: 11 | number: 0 12 | 13 | requirements: 14 | build: 15 | - cmake 16 | - fftw 17 | run: 18 | - fftw 19 | 20 | test: 21 | commands: 22 | - lsdtt-basic-metrics 23 | - lsdtt-channel-extraction 24 | - lsdtt-chi-mapping 25 | 26 | about: 27 | home: https://github.com/LSDtopotools/LSDTT_public 28 | license: GPLv3 29 | summary: 'Software for topographic analysis' 30 | -------------------------------------------------------------------------------- /docker_files/lsdtt_alpine/dockerfile: -------------------------------------------------------------------------------- 1 | # This is an alpine linux installation 2 | 3 | FROM alpine 4 | MAINTAINER Simon Mudd (simon.m.mudd@ed.ac.uk) and Fiona Clubb (clubb@uni-potsdam.de) 5 | 6 | # install essential packages 7 | RUN apk upgrade -U && \ 8 | apk update && \ 9 | apk add --virtual build-dependencies build-base gcc wget git bash && \ 10 | apk add --repository http://dl-cdn.alpinelinux.org/alpine/edge/main libressl2.7-libcrypto && \ 11 | apk add gdal --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing && \ 12 | apk add fftw-dev cmake && \ 13 | rm -rf /var/cache/apk/* && \ 14 | rm -rf /tmp/* 15 | 16 | # update to avoid weird apk error 17 | RUN apk update 18 | 19 | # Add an LSDTopoTools working directory 20 | WORKDIR /LSDTopoTools/ 21 | -------------------------------------------------------------------------------- /docker_files/lsdtt_docs/dockerfile: -------------------------------------------------------------------------------- 1 | # This is a dockerfile for the LSDTT documentation, only slightly modified from this dockerfile: 2 | # https://github.com/asciidoctor/docker-asciidoctor 3 | 4 | FROM alpine:3.7 5 | 6 | LABEL MAINTAINERS="Simon Mudd " 7 | 8 | ARG asciidoctor_version=1.5.7.1 9 | ARG asciidoctor_pdf_version=1.5.0.alpha.16 10 | 11 | ENV ASCIIDOCTOR_VERSION=${asciidoctor_version} \ 12 | ASCIIDOCTOR_PDF_VERSION=${asciidoctor_pdf_version} 13 | 14 | # Installing package required for the runtime of 15 | # any of the asciidoctor-* functionnalities 16 | RUN apk add --no-cache \ 17 | bash \ 18 | curl \ 19 | ca-certificates \ 20 | findutils \ 21 | font-bakoma-ttf \ 22 | graphviz \ 23 | make \ 24 | openjdk8-jre \ 25 | py2-pillow \ 26 | py-setuptools \ 27 | python2 \ 28 | ruby \ 29 | ruby-mathematical \ 30 | ttf-liberation \ 31 | unzip \ 32 | which 33 | 34 | # Installing Ruby Gems needed in the image 35 | # including asciidoctor itself 36 | RUN apk add --no-cache --virtual .rubymakedepends \ 37 | build-base \ 38 | libxml2-dev \ 39 | ruby-dev \ 40 | && gem install --no-document \ 41 | "asciidoctor:${ASCIIDOCTOR_VERSION}" \ 42 | asciidoctor-confluence \ 43 | asciidoctor-diagram \ 44 | asciidoctor-epub3:1.5.0.alpha.7 \ 45 | asciidoctor-mathematical \ 46 | "asciidoctor-pdf:${ASCIIDOCTOR_PDF_VERSION}" \ 47 | asciidoctor-revealjs \ 48 | coderay \ 49 | epubcheck:3.0.1 \ 50 | haml \ 51 | kindlegen:3.0.3 \ 52 | pygments.rb \ 53 | rake \ 54 | rouge \ 55 | slim \ 56 | thread_safe \ 57 | tilt \ 58 | awesome_print \ 59 | bundler \ 60 | && apk del -r --no-cache .rubymakedepends 61 | 62 | # Installing Python dependencies for additional 63 | # functionnalities as diagrams or syntax highligthing 64 | RUN apk add --no-cache --virtual .pythonmakedepends \ 65 | build-base \ 66 | python2-dev \ 67 | py2-pip \ 68 | && pip install --upgrade pip \ 69 | && pip install --no-cache-dir \ 70 | actdiag \ 71 | 'blockdiag[pdf]' \ 72 | nwdiag \ 73 | Pygments \ 74 | seqdiag \ 75 | && apk del -r --no-cache .pythonmakedepends 76 | 77 | WORKDIR /documents 78 | 79 | -------------------------------------------------------------------------------- /docker_files/lsdtt_pcl/dockerfile: -------------------------------------------------------------------------------- 1 | # This is the LSDTopoTools container that includes the point cloud library (PCL) 2 | # PCL is HUGE. Also it won't compile on the lightweight alpine container so the Linxu build is also large 3 | # This means that this container is *MUCH* larger than the lsdtt-alpine container. 4 | # You should only use this container if you intend to use the components of LSDTopoTools 5 | # that require the point cloud library. 6 | # These include 7 | # * The terrace code 8 | # * Code that includes swath profiling 9 | # * Any code that includes biomass 10 | # If you are not a developer, the only place you will really encounter PCL is in the terrace code. 11 | # If you do not plan to use this, we suggest using the lsdtt-alpine container. 12 | 13 | # Pull base image. 14 | FROM ubuntu:18.04 15 | MAINTAINER Simon Mudd (simon.m.mudd@ed.ac.uk) and Fiona Clubb (clubb@uni-potsdam.de) 16 | 17 | # Need this to shortcut the stupid tzdata noninteractive thing 18 | ARG DEBIAN_FRONTEND=noninteractive 19 | 20 | # These are the basic build tools 21 | RUN apt-get update && apt-get install -y \ 22 | apt-utils \ 23 | tzdata \ 24 | build-essential \ 25 | git \ 26 | cmake \ 27 | && rm -rf /var/lib/apt/lists/* 28 | 29 | # Now some extra bells and whistles 30 | RUN apt-get update && apt-get install -y \ 31 | gdal-bin \ 32 | libfftw3-dev \ 33 | python-gdal \ 34 | && rm -rf /var/lib/apt/lists/* 35 | 36 | # And this is the point cloud library 37 | 38 | # install pcl 39 | RUN apt-get update && apt-get install -y \ 40 | libpcl-dev \ 41 | && rm -rf /var/lib/apt/lists/* 42 | 43 | # Finally some projection tools 44 | RUN apt-get update && apt-get install -y \ 45 | libproj-dev \ 46 | && rm -rf /var/lib/apt/lists/* 47 | 48 | WORKDIR /LSDTopoTools 49 | -------------------------------------------------------------------------------- /history.asc: -------------------------------------------------------------------------------- 1 | = History 2 | 3 | == 0.1 (2018-13-12) 4 | 5 | 6 | * First beta release 7 | 8 | == 0.2 (2020-22-04) 9 | 10 | * New routines for analysing concavity index 11 | * Adding new routines for CAIRN 12 | 13 | == 0.3 (2020-22-04) 14 | 15 | * More updates to the concavity routines 16 | * Some updates to source code of MuddPILE including 3D lithology 17 | * adding functionality to CAIRN so you can calculate without topographic shielding 18 | 19 | == 0.4 (2021-03-21) 20 | 21 | * Fixes a bug in the geojson printing that caused later versions of QGIS to reject the geojson files. 22 | * Includes much more functionality on the hillslope flow routing routines including better coverage of the ridgetops, easier selections of basins and lower memory use 23 | * Adds a swath mapping tool that does not depend on the point cloud library (meaning that the terrace and floodplain code may become available here in the next release). 24 | * And some other minor bug fixes and efficiencies. 25 | 26 | == 0.5 (2021-12-17) 27 | 28 | * This update provides some improvements to the floodplain extraction algorithms. 29 | * In addition there are some new features in basic metrics for raster manipulation. 30 | 31 | * We have also included help and version flags to the command line tools. 32 | * If you call a command line tool with the flag -h then you will produce a csv explaining all the options for each tool. 33 | 34 | == 0.6 (2020-09-03) 35 | 36 | == 0.7 (2022-09-13) 37 | 38 | * This includes a number of improvements to the valley width extraction algorithms including those used in the paper https://doi.org/10.5194/esurf-10-437-2022 (SMM and FJC) 39 | * This release has a new dependency on the OpenCV library. The programs will compile without this library but the valley metrics component will only compile with OpenCV. (FJC) 40 | * This version removed dependency on the Point Cloud Library. (FJC) 41 | * It also includes updated functionality for the cosmogenic tools, so the analyses from the CAIRN (Mudd et al 2016) method are streamlined. (SMM) 42 | 43 | == 0.8 (2023-05-03) 44 | 45 | * Additions to channel extraction include getting longest channel, including more information in the output files, and an option to print channels as shapefiles. (SMM) 46 | * A number of changes to the cosmo tool including better accounting for a column, an interface to bring in transient erosion rates, better support for CRN, smoother operation of the nesting functions, and fixes to the shielding calculations that allow you to compute erosion rates in one step. (SMM) 47 | * Added a function for creating steady state fluvial landscapes (SMM) 48 | * Included some new metrics, most notably the normalised concavity index or NCI that was used in Chen et al Nature paper. (SMM) 49 | * Added a routine that facilitates tagging of major drainage divides. (SMM) 50 | * Added perona-malik filter to hillslope analysis (FJC) 51 | * added a small function to analyse channel tips for a channel extraction routine (SMM) 52 | * Other minor bug and typo fixes. (SMM and FJC) 53 | 54 | == 0.9 (2023-06-23) 55 | 56 | * Added function in lsdtt-basic-metrics to extract basin outlines (SMM) 57 | * Added function in lsdtt-basic-metrics to get the bearing of channel segments (SMM) 58 | * Added function in lsdtt-basic-metrics to print flow direction codes in ArcMap format (SMM) 59 | * More testing of lsdtt-valley-metrics to reduce bugs and give more informative error messages. (SMM) 60 | * Added swath output to the terrace routine (SMM) 61 | * Some testing of ridge extraction and minor bug fixes (FJC) -------------------------------------------------------------------------------- /lsdtt2_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This is a startup script for LSDTopoTools 4 | # It clones the LSDTopoTools2 repository into a directory of your choice 5 | # it then builds the code from there. 6 | # Author: SMM 7 | # Date: 22/05/2020 8 | 9 | echo "Hello, I am going to set up LSDTopoTools2 for you." 10 | 11 | 12 | echo "First, would you like me to see if you already have an LSDTopoTools2 directory? " 13 | echo "This uses a find function so it might take a while." 14 | 15 | while true; do 16 | echo "Enter y or n" 17 | read yn 18 | case $yn in 19 | [Yy]* ) echo "Checking..."; 20 | find / -type d -name "LSDTopoTools2"; 21 | echo "end check."; 22 | echo "If a directory has been found it means you might already have LSDTopoTools2." 23 | echo "If you don't want to install LSDTopoTools2 twice," 24 | echo "use this directory as the installation path in the options below." 25 | sleep 3 26 | break;; 27 | [Nn]* ) echo "Okay, I'll move on"; break;; 28 | * ) echo "Please answer yes or no.";; 29 | esac 30 | done 31 | 32 | echo "====================================================================" 33 | echo "Okay, now, I'd like to know where you want me to set up." 34 | echo "Your current directory is: " 35 | echo $PWD 36 | echo "Where yould you like me to put LSDTopoTools?" 37 | echo "I will make an LSDTopoTools directory here if it doesn't exist" 38 | echo "1 -- I am in an LSDTopoTools docker container. Make all the choices for me." 39 | echo "2 -- Put it in this directory." 40 | echo "3 -- Put it in my home directory." 41 | echo "4 -- Put it somewhere else. I'll ask you where you want it if you make this choice." 42 | echo "5 -- I have conda. Just install it. Note that this doesn't create any of the test data directories" 43 | read choice 44 | 45 | 46 | echo "You chose:" 47 | echo $choice 48 | ROOT_DIR="/root" 49 | 50 | if [ $choice -eq 1 ]; then 51 | echo "You are in an LSDTopoTools docker container. I am going to make the choices for you." 52 | BASE_DIR=$HOME 53 | echo "The base directory is" 54 | echo $BASE_DIR 55 | if [ $BASE_DIR = $ROOT_DIR ]; then 56 | BASE_DIR="" 57 | fi 58 | elif [ $choice -eq 2 ]; then 59 | echo "You chose this directory" 60 | BASE_DIR=$PWD 61 | elif [ $choice -eq 3 ]; then 62 | echo "I will put LSDTopoTools2 in your home directory" 63 | BASE_DIR=$HOME 64 | if [ $BASE_DIR = $ROOT_DIR ]; then 65 | BASE_DIR="" 66 | fi 67 | elif [ $choice -eq 4 ]; then 68 | echo "You chose somewhere else." 69 | echo "Please enter the full directory path, without trailing slash, where you want to install LSDTopoTools" 70 | read choice_dir 71 | echo "Checking to see if" 72 | echo $choice_dir 73 | echo "exists" 74 | if [ -d "$choice_dir" ]; then 75 | echo "The directory exists. Setting that as the LSDTopoTools base directory" 76 | BASE_DIR=$choice_dir 77 | else 78 | echo "The directory doesn't exist. I am exiting. Please create your directory of choice using mkdir" 79 | exit 1 80 | fi 81 | elif [ $choice -eq 5 ]; then 82 | echo "You have conda? Excellent. I will just install the tools." 83 | if conda ; then 84 | conda install -y -c conda-forge lsdtopotools 85 | else 86 | echo "You don't have conda installed. Exiting." 87 | exit 1 88 | fi 89 | else 90 | echo "Sorry, I didn't understand that. Please try again." 91 | exit 1 92 | fi 93 | 94 | echo "You have chosen to install LSDTopoTools here:" 95 | echo $BASE_DIR 96 | 97 | # Now set up all the subsidiary directories 98 | SRC_DIR="$BASE_DIR/LSDTopoTools/LSDTopoTools2/src/" 99 | LSD_DIR="$BASE_DIR/LSDTopoTools" 100 | WRK_DIR="$BASE_DIR/LSDTopoTools/LSDTopoTools2" 101 | DATA_DIR="$BASE_DIR/LSDTopoTools/data/ExampleTopoDatasets" 102 | 103 | # Make the LSDTopoTools directory if it doesn't exist 104 | if [ -d $LSD_DIR ] 105 | then 106 | echo "LSDTopoTools directory exists!" 107 | else 108 | echo "LSDTopoTools directory doesnt' exist. I'm making one" 109 | mkdir $LSD_DIR 110 | fi 111 | 112 | 113 | # clone or pull the repo, depending on what is in there 114 | # check if the files have been cloned 115 | if [ -f $SRC_DIR/LSDRaster.cpp ] 116 | then 117 | echo "The LSDTopoTools2 repository exists, updating to the latest version." 118 | git --work-tree=$WRK_DIR --git-dir=$WRK_DIR.git pull origin master 119 | else 120 | echo "Cloning the LSDTopoTools2 repository" 121 | git clone https://github.com/LSDtopotools/LSDTopoTools2.git $WRK_DIR 122 | fi 123 | 124 | # Change the working directory to that of LSDTopoTools2/src 125 | #echo "I am going to try to build LSDTopoTools2." 126 | cd $SRC_DIR 127 | echo "The current directory is:" 128 | echo $PWD 129 | echo "Calling the build script." 130 | sh build.sh 131 | 132 | 133 | echo "=====================================================================" 134 | echo "Would you like me to get the Example data?" 135 | echo "It is ~200Mb" 136 | 137 | while true; do 138 | echo "Enter y or n" 139 | read yn 140 | case $yn in 141 | [Yy]* ) echo "Okay, checking for data..."; 142 | if [ -d $DATA_DIR ] 143 | then 144 | echo "The Example data already exists!." 145 | else 146 | echo "Cloning the LSDTopoTools2 repository" 147 | git clone https://github.com/LSDtopotools/ExampleTopoDatasets.git $DATA_DIR 148 | fi 149 | break;; 150 | [Nn]* ) echo "Okay, I'll move on"; break;; 151 | * ) echo "Please answer yes or no.";; 152 | esac 153 | done 154 | 155 | 156 | 157 | # Now update the path 158 | echo "Now I'll add the LSDTopoTools command line programs to your path." 159 | export PATH=$BASE_DIR/LSDTopoTools/LSDTopoTools2/bin:$PATH 160 | echo "Your path is now:" 161 | echo $PATH 162 | exec /bin/bash 163 | 164 | 165 | -------------------------------------------------------------------------------- /lsdtt2_terminal.sh: -------------------------------------------------------------------------------- 1 | # This script spawns a new shell that has the correct path to the lsdtopotools2 driver functions 2 | # Written by Simon M Mudd 3 | # 25-Sept-2018 4 | 5 | # This sorts out the directory into which the code will be built 6 | bindir=/bin 7 | fullbindir="$PWD$bindir" 8 | echo "The full directory for binary files is:" 9 | echo $fullbindir 10 | 11 | # This is the name of one of the files I will check 12 | lsdttfile=/lsdtt-basic-metrics 13 | fullfile="$fullbindir$lsdttfile" 14 | echo "The name of the driver file is" 15 | echo $fullfile 16 | 17 | # I am checking to see if you have the binary files 18 | if [ ! -f $fullfile ]; then 19 | echo "I did not find the binary files! I need to compile." 20 | echo "Go into the /src directory and run build.sh" 21 | else 22 | echo "The binary files exist. I am updating the path and spawning a new terminal." 23 | echo "You can now use the lsdtt tools from this terminal." 24 | echo "You will need to use this script every time you want to start an LSDTopoTools session." 25 | export PATH=$fullbindir:$PATH 26 | exec /bin/bash 27 | fi 28 | -------------------------------------------------------------------------------- /readme.asc: -------------------------------------------------------------------------------- 1 | = LSDTopoTools 0.9 2 | 3 | image:https://travis-ci.org/LSDtopotools/LSDTopoTools_CRNBasinwide.svg?branch=master[link="https://travis-ci.org/LSDtopotools/LSDTopoTools2"] 4 | image:https://img.shields.io/badge/License-GPL%20v3-blue.svg[link="https://www.gnu.org/licenses/gpl-3.0"] 5 | 6 | == Overview 7 | 8 | This is the *LSDTopoTools2* software package. It is part of the *LSDTopoTools* family of topographic analysis tools. These include: 9 | 10 | * *LSDTopoTools2*: A series of command line tools that are used for topographic analysis. Installation instructions below. 11 | * *lsdviztools*: A python package for visualising *LSDTopoTools2* outputs. See https://github.com/LSDtopotools/lsdviztools 12 | * *lsdtopytools*: The python bindings for *LSDTopoTools*. Still under construction. https://github.com/LSDtopotools/lsdtopytools 13 | 14 | The *LSDTopoTools2* repository contains the source code for 6 command line tools: 15 | 16 | * `lsdtt-basic-metrics`: Basic topographic analysis. Surface metrics, basic channel and basin extraction, raster preprocessing and other simple routines. 17 | * `lsdtt-channel-extraction`: Extracts channels. This uses a variety of algorthims suited for topographic data that is better than 10m grid resolution and ideally from lidar data (3m resolution or better). 18 | * `lsdtt-chi-mapping`: Routines for so-called chi analysis: this is used in tectonic geomorphology. 19 | * `lsdtt-cosmo-tool`: Tools for calculating erosion rates based on 10Be and 26Al concentrations measured in stream sediments and soils. 20 | * `lsdtt-hillslope-channel-coupling`: Routines for hilltop flow routing and linking ridgetop pixels to channels. 21 | * `lsdtt-valley-metrics`: Routines for valley and terrace extraction 22 | 23 | == Documentation 24 | 25 | * You can see all the options by using a `-h` flag after the command line tool. 26 | * You can see the version using the `-v` flag 27 | * The main documentation for *LSDTopoTools* can be found here: https://lsdtopotools.github.io/LSDTT_documentation/ 28 | * Full installation instructions: https://lsdtopotools.github.io/LSDTT_documentation/LSDTT_installation.html 29 | ** The shortcut is to install https://docs.conda.io/en/latest/miniconda.html[miniconda] and then run `conda install lsdtopotools` 30 | * Simple usage is explained in https://lsdtopotools.github.io/LSDTT_documentation/LSDTT_basic_usage.html 31 | 32 | == Update history 33 | 34 | * `0.9` More testing of terrace and floodplain extraction. A few new routines in basic metrics. See `history.asc` file. 35 | * `0.8` Improved cosmogenics. Shapefile from channel extraction. Generation of steady state landscapes. See `history.asc` file. 36 | * `0.7` improved valley extraction. Large changes to the cosmogenic tools including forward modelling component. This version removes the dependency on the point cloud library and replaces it with dependency on the OpenCV library. 37 | * `0.6` Added valley extraction. This had limited functionality since it did not have the valley width tools. 38 | * `0.5` Now includes help files. 39 | 40 | == Basic Installation 41 | 42 | Below are several methods for installing *LSDTopoTools2*. 43 | 44 | === Conda installation 45 | 46 | . Install https://docs.conda.io/en/latest/miniconda.html[miniconda] 47 | . Set up an environment (if you don't know how to do that use google) 48 | . `$ conda install -c conda-forge lsdtopotools` 49 | + 50 | . As of 23/06/2023 we are updating feedstocks so version 0.9 should be ready soon. All previous versions are available. 51 | WARNING: Currently doesn't work on Windows. 52 | 53 | === Use the docker container 54 | 55 | . Install https://www.docker.com/products/docker-desktop[docker for windows io MacOS], or https://docs.docker.com/engine/install/ubuntu/[docker engine on linux] 56 | . Pull our full *lsdtopotools* container: 57 | + 58 | [source,console] 59 | ---- 60 | $ docker pull lsdtopotools/lsdtt_pytools_docker 61 | ---- 62 | + 63 | . Run the container 64 | + 65 | [source,console] 66 | ---- 67 | $ docker run -it -v C:\LSDTopoTools:/LSDTopoTools lsdtopotools/lsdtt_pytools_docker 68 | ---- 69 | + 70 | . *LSDTopoTools2* is already installed! 71 | . You can alternatively use *LSDTopoTools through an interactive environment using this container. See the readme here: https://hub.docker.com/r/lsdtopotools/lsdtt_pytools_docker 72 | 73 | 74 | === Build locally 75 | 76 | . Clone the repository. 77 | . Go into the `src` directory. 78 | . Run 79 | + 80 | [source,console] 81 | ---- 82 | $ sh build.sh 83 | ---- 84 | + 85 | . This compiles the source code. The programs will be moved into the `bin` directory. To make these accessible from anywhere in your current terminal session, you need to: 86 | .. Go into the main repository directory (if you are in `src`, then use `cd ..`). 87 | .. Run: 88 | + 89 | [source,console] 90 | ---- 91 | $ sh lsdtt2_terminal.sh 92 | ---- 93 | + 94 | 95 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) 2 | project(LSDTopoTools) 3 | 4 | # Dependencies 5 | # ============ 6 | find_package(PkgConfig REQUIRED) 7 | pkg_search_module(FFTW REQUIRED fftw3 IMPORTED_TARGET) 8 | include_directories(PkgConfig::FFTW) 9 | link_libraries (PkgConfig::FFTW) 10 | 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-offsetof -O3 -std=c++11") 14 | 15 | # We test if the open cv library is found. 16 | # If not we compile without lsdtt-valley-width program 17 | # OpenCV 18 | find_package(OpenCV) 19 | if(OpenCV_FOUND) 20 | message("I found OpenCV and am compiling the floodplain code") 21 | include_directories( ${OpenCV_INCLUDE_DIRS}) 22 | 23 | # Build 24 | # ===== 25 | set(LIB_HEADERS 26 | LSDBasin.hpp 27 | LSDChiTools.hpp 28 | LSDChiNetwork.hpp 29 | LSDChannel.hpp 30 | LSDCosmoData.hpp 31 | LSDCosmoRaster.hpp 32 | LSDCRNParameters.hpp 33 | LSDFlowInfo.hpp 34 | LSDIndexChannel.hpp 35 | LSDIndexChannelTree.hpp 36 | LSDIndexRaster.hpp 37 | LSDJunctionNetwork.hpp 38 | LSDMostLikelyPartitionsFinder.hpp 39 | LSDParameterParser.hpp 40 | LSDParticle.hpp 41 | LSDParticleColumn.hpp 42 | LSDRaster.hpp 43 | LSDRasterAggregator.hpp 44 | LSDRasterInfo.hpp 45 | LSDRasterMaker.hpp 46 | LSDRasterSpectral.hpp 47 | LSDSoilHydroRaster.hpp 48 | LSDStatsTools.hpp 49 | LSDShapeTools.hpp 50 | LSDSpatialCSVReader.hpp 51 | LSDStrahlerLinks.hpp 52 | LSDFloodplain.hpp 53 | LSDTerrace.hpp 54 | ) 55 | 56 | string(REGEX REPLACE "([^;]+).hpp" "\\1.cpp" LIB_SOURCES "${LIB_HEADERS}") 57 | 58 | set(EXE_SOURCES 59 | lsdtt-drivers/lsdtt-basic-metrics.cpp 60 | lsdtt-drivers/lsdtt-channel-extraction.cpp 61 | lsdtt-drivers/lsdtt-chi-mapping.cpp 62 | lsdtt-drivers/lsdtt-cosmo-tool.cpp 63 | lsdtt-drivers/lsdtt-hillslope-channel-coupling.cpp 64 | lsdtt-drivers/lsdtt-valley-metrics.cpp 65 | ) 66 | 67 | set(EXE_FILES) 68 | 69 | add_library(${PROJECT_NAME} ${LIB_SOURCES} ${LIB_HEADERS} ) 70 | 71 | foreach(src_file ${EXE_SOURCES}) 72 | string(REGEX REPLACE "([^;]+)/([^;]+).cpp" "\\2" exe_file ${src_file}) 73 | list(APPEND EXE_FILES ${exe_file}) 74 | add_executable(${exe_file} ${src_file}) 75 | target_link_libraries(${exe_file} ${PROJECT_NAME} PkgConfig::FFTW) 76 | target_link_libraries(${exe_file} ${PROJECT_NAME} ${OpenCV_LIBS} ) 77 | endforeach(src_file ${EXE_SOURCES}) 78 | 79 | 80 | # Install 81 | # ======= 82 | include(GNUInstallDirs) 83 | include(CMakePackageConfigHelpers) 84 | 85 | install( 86 | TARGETS ${EXE_FILES} ${PROJECT_NAME} 87 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 88 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 89 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 90 | ) 91 | else() 92 | message("I am compiling without the openCV library") 93 | 94 | set(LIB_HEADERS 95 | LSDBasin.hpp 96 | LSDChiTools.hpp 97 | LSDChiNetwork.hpp 98 | LSDChannel.hpp 99 | LSDCosmoData.hpp 100 | LSDCosmoRaster.hpp 101 | LSDCRNParameters.hpp 102 | LSDFlowInfo.hpp 103 | LSDIndexChannel.hpp 104 | LSDIndexChannelTree.hpp 105 | LSDIndexRaster.hpp 106 | LSDJunctionNetwork.hpp 107 | LSDMostLikelyPartitionsFinder.hpp 108 | LSDParameterParser.hpp 109 | LSDParticle.hpp 110 | LSDParticleColumn.hpp 111 | LSDRaster.hpp 112 | LSDRasterAggregator.hpp 113 | LSDRasterInfo.hpp 114 | LSDRasterMaker.hpp 115 | LSDRasterSpectral.hpp 116 | LSDSoilHydroRaster.hpp 117 | LSDStatsTools.hpp 118 | LSDShapeTools.hpp 119 | LSDSpatialCSVReader.hpp 120 | LSDStrahlerLinks.hpp 121 | ) 122 | 123 | string(REGEX REPLACE "([^;]+).hpp" "\\1.cpp" LIB_SOURCES "${LIB_HEADERS}") 124 | 125 | set(EXE_SOURCES 126 | lsdtt-drivers/lsdtt-basic-metrics.cpp 127 | lsdtt-drivers/lsdtt-channel-extraction.cpp 128 | lsdtt-drivers/lsdtt-chi-mapping.cpp 129 | lsdtt-drivers/lsdtt-cosmo-tool.cpp 130 | lsdtt-drivers/lsdtt-hillslope-channel-coupling.cpp 131 | ) 132 | 133 | set(EXE_FILES) 134 | 135 | add_library(${PROJECT_NAME} ${LIB_SOURCES} ${LIB_HEADERS} ) 136 | 137 | foreach(src_file ${EXE_SOURCES}) 138 | string(REGEX REPLACE "([^;]+)/([^;]+).cpp" "\\2" exe_file ${src_file}) 139 | list(APPEND EXE_FILES ${exe_file}) 140 | add_executable(${exe_file} ${src_file}) 141 | target_link_libraries(${exe_file} ${PROJECT_NAME} fftw3) 142 | endforeach(src_file ${EXE_SOURCES}) 143 | 144 | 145 | # Install 146 | # ======= 147 | include(GNUInstallDirs) 148 | include(CMakePackageConfigHelpers) 149 | 150 | install( 151 | TARGETS ${EXE_FILES} ${PROJECT_NAME} 152 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 153 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 154 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 155 | ) 156 | endif() 157 | 158 | -------------------------------------------------------------------------------- /src/LSDCloudRaster.cpp: -------------------------------------------------------------------------------- 1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | // LSDCloudRaster.cpp 3 | //------------------------------------------------------------------------------ 4 | // This code is based on LSDCloudBase but does not require the liblas software. 5 | // It cannot read in las files but instead uses the cloud functions interfacing 6 | // with LSDRaster objects 7 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 8 | // 9 | // This object is written by 10 | // David T. Milodowski, University of Edinburgh 11 | // Simon M. Mudd, University of Edinburgh 12 | // Fiona J. Clubb, University of Edinburgh 13 | // 14 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 15 | // 16 | // Version 0.0.1 28/03/17 17 | // Prerequisite software packages: TNT, PCL 18 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | // LSDTopotools objects 28 | #include "LSDRaster.hpp" 29 | #include "LSDCloudRaster.hpp" 30 | #include "LSDShapeTools.hpp" 31 | 32 | // PCL 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | // TNT 39 | #include "TNT/tnt.h" 40 | 41 | using namespace std; 42 | using namespace TNT; 43 | 44 | #ifndef LSDCloudRaster_CPP 45 | #define LSDCloudRaster_CPP 46 | 47 | //------------------------------------------------------------------------------ 48 | // OPERATOR FUNCTIONS 49 | // Stuff to create a point cloud, and other useful stuff will go here 50 | LSDCloudRaster& LSDCloudRaster::operator=(const LSDCloudRaster& rhs) 51 | { 52 | if (&rhs != this) 53 | { 54 | create(rhs.get_NPts(),rhs.get_XMin(),rhs.get_XMax(),rhs.get_YMin(),rhs.get_YMax(),rhs.get_XOffset(),rhs.get_YOffset(), 55 | rhs.get_theCloud(),rhs.get_OctreeResolution()); 56 | } 57 | return *this; 58 | } 59 | 60 | // the create function. This is default and throws an error 61 | void LSDCloudRaster::create() 62 | { 63 | cout << "LSDCloudRaster line 63 Warning you have an empty LSDCloudRaster" << endl; 64 | exit(EXIT_FAILURE); 65 | } 66 | 67 | void LSDCloudRaster::create(int n_pts, float x_min, float x_max, float y_min, float y_max, 68 | float x_offset, float y_offset, pcl::PointCloud::Ptr cloud, const double resolution) 69 | { 70 | NPts = n_pts; 71 | pcl::PointCloud::Ptr theCloud; 72 | if (theCloud->points.size() != NPts) 73 | { 74 | cout << "LSDCloudBase line 75 number of points in point cloud is not the same as stated in NPts! Return to Cloud Base!" << endl; 75 | exit(EXIT_FAILURE); 76 | } 77 | // bounding box of point cloud 78 | XMin = x_min; 79 | YMin = y_min; 80 | XMax = x_max; 81 | YMax = y_max; 82 | // origin shift 83 | XOffset = x_offset; 84 | YOffset = y_offset; 85 | 86 | // Octree spatial structure 87 | OctreeResolution = resolution; 88 | } 89 | 90 | // This creates an LSDCloud from a LSDRaster 91 | void LSDCloudRaster::create(LSDRaster& raster) 92 | { 93 | OctreeResolution = raster.get_DataResolution(); 94 | raster_to_cloud(raster); 95 | } 96 | // Read in data from a PointData object (see LSDShapeTools module) 97 | void LSDCloudRaster::create(PointData& point_data, LSDRaster& raster) 98 | { 99 | OctreeResolution = raster.get_DataResolution(); 100 | PointData_to_cloud(point_data,raster); 101 | } 102 | 103 | // Read in data from an LSDRaster 104 | void LSDCloudRaster::raster_to_cloud(LSDRaster& raster) 105 | { 106 | XOffset = raster.get_XMinimum(); 107 | YOffset = raster.get_YMinimum(); 108 | NPts = 0; 109 | vector x_coordinates, y_coordinates, zeta_values; 110 | for(int i = 0; i < raster.get_NRows(); ++i) 111 | { 112 | for(int j = 0; j < raster.get_NCols(); ++j) 113 | { 114 | if(raster.get_data_element(i,j) != raster.get_NoDataValue()) 115 | { 116 | zeta_values.push_back(raster.get_data_element(i,j)); 117 | x_coordinates.push_back(float(j)); 118 | y_coordinates.push_back((float(raster.get_NRows() - 1) - float(i))); 119 | ++NPts; 120 | } 121 | } 122 | } 123 | 124 | // Generate pointcloud data structure 125 | pcl::PointCloud::Ptr cloud (new pcl::PointCloud); 126 | theCloud = cloud; 127 | 128 | theCloud->width = zeta_values.size(); 129 | theCloud->height = 1; 130 | theCloud->points.resize (theCloud->width * theCloud->height); 131 | 132 | // Loop through the .las file, reading the points into the new data structure. 133 | for (size_t i = 0; i < theCloud->points.size(); ++i) 134 | { 135 | theCloud->points[i].x = x_coordinates[i]; 136 | theCloud->points[i].y = y_coordinates[i]; 137 | theCloud->points[i].z = 0; 138 | theCloud->points[i].intensity = zeta_values[i]; 139 | } 140 | cloudOctree = (new pcl::octree::OctreePointCloudSearch(OctreeResolution) ); 141 | cloudOctree->setInputCloud(theCloud); 142 | cloudOctree->addPointsFromInputCloud(); 143 | } 144 | // Read in data from a PointData object (see LSDShapeTools module) 145 | void LSDCloudRaster::PointData_to_cloud(PointData& point_data, LSDRaster& raster) 146 | { 147 | XOffset = raster.get_XMinimum(); 148 | YOffset = raster.get_YMinimum(); 149 | vector x_coordinates, y_coordinates, zeta_values; 150 | NPts = 0; 151 | x_coordinates.push_back(point_data.X[0]-XOffset); 152 | y_coordinates.push_back(point_data.Y[0]-YOffset); 153 | ++NPts; 154 | XMin = x_coordinates[0]; 155 | YMin = y_coordinates[0]; 156 | XMax = x_coordinates[0]; 157 | YMax = y_coordinates[0]; 158 | for(int i = 1; i < point_data.X.size(); ++i) 159 | { 160 | x_coordinates.push_back(point_data.X[i]-XOffset); 161 | y_coordinates.push_back(point_data.Y[i]-YOffset); 162 | ++NPts; 163 | if(x_coordinates[i] < XMin) XMin = x_coordinates[i]; 164 | if(x_coordinates[i] > XMax) XMax = x_coordinates[i]; 165 | if(y_coordinates[i] < YMin) YMin = y_coordinates[i]; 166 | if(y_coordinates[i] > YMax) YMax = y_coordinates[i]; 167 | } 168 | // Generate pointcloud data structure 169 | pcl::PointCloud::Ptr cloud (new pcl::PointCloud); 170 | theCloud = cloud; 171 | 172 | theCloud->width = y_coordinates.size(); 173 | theCloud->height = 1; 174 | theCloud->points.resize (theCloud->width * theCloud->height); 175 | 176 | // Loop through the .las file, reading the points into the new data structure. 177 | for (size_t i = 0; i < theCloud->points.size(); ++i) 178 | { 179 | theCloud->points[i].x = x_coordinates[i]; 180 | theCloud->points[i].y = y_coordinates[i]; 181 | theCloud->points[i].z = 0; 182 | theCloud->points[i].intensity = 0; 183 | } 184 | cloudOctree = (new pcl::octree::OctreePointCloudSearch(OctreeResolution) ); 185 | cloudOctree->setInputCloud(theCloud); 186 | cloudOctree->addPointsFromInputCloud(); 187 | } 188 | 189 | //------------------------------------------------------------------------------ 190 | // SEARCHING TOOLS 191 | // a set of tools to conduct search operations on the structured point cloud 192 | // hosted in the LSDCloud object. 193 | 194 | // Conducts a focal search (in the xy plane), to find all points within defined 195 | // search radius 196 | void LSDCloudRaster::RadiusSearch2D(float searchPoint_x, float searchPoint_y, float searchRadius, 197 | vector& pointValues, vector& pointIndex, vector& pointSquaredDistance) 198 | { 199 | pcl::PointXYZI searchPoint; 200 | searchPoint.x = searchPoint_x; 201 | searchPoint.y = searchPoint_y; 202 | searchPoint.z = 0; 203 | searchPoint.intensity = 0; 204 | 205 | if (cloudOctree->radiusSearch (searchPoint, searchRadius, pointIndex, pointSquaredDistance) > 0) 206 | { 207 | int NumberOfPoints = pointIndex.size(); 208 | for (int i = 0; i < NumberOfPoints; ++i) 209 | { 210 | pointValues.push_back( theCloud->points[ pointIndex[i] ].intensity ); 211 | } 212 | } 213 | else 214 | { 215 | cout << "No returns in search radius" << endl; 216 | } 217 | } 218 | // Conducts a focal search (in the xy plane), to find the nearest K points 219 | void LSDCloudRaster::NearestNeighbourSearch2D(float searchPoint_x, float searchPoint_y, int K, 220 | vector& pointValues, vector& pointIndex, vector& pointSquaredDistance) 221 | { 222 | pcl::PointXYZI searchPoint; 223 | searchPoint.x = searchPoint_x; 224 | searchPoint.y = searchPoint_y; 225 | searchPoint.z = 0; 226 | searchPoint.intensity = 0; 227 | 228 | vector P_i_pointIdxNKNSearch; 229 | vector P_i_pointNKNSquaredDistance; 230 | if (cloudOctree->nearestKSearch (searchPoint, K, pointIndex, pointSquaredDistance) > 0) 231 | { 232 | int NumberOfPoints = pointIndex.size(); 233 | for (int i = 0; i < NumberOfPoints; ++i) 234 | { 235 | pointValues.push_back( theCloud->points[ pointIndex[i] ].intensity ); 236 | } 237 | } 238 | else 239 | { 240 | cout << "No points to select" << endl; 241 | } 242 | } 243 | 244 | 245 | #endif 246 | -------------------------------------------------------------------------------- /src/LSDCloudRaster.hpp: -------------------------------------------------------------------------------- 1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | // LSDCloudRaster.hpp 3 | //------------------------------------------------------------------------------ 4 | // This code is based on LSDCloudBase but does not require the liblas software. 5 | // It cannot read in las files but instead uses the cloud functions interfacing 6 | // with LSDRaster objects 7 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 8 | // 9 | // This object is written by 10 | // David T. Milodowski, University of Edinburgh 11 | // Simon M. Mudd, University of Edinburgh 12 | // Fiona J. Clubb, University of Edinburgh 13 | // 14 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 15 | // 16 | // Version 0.0.1 28/03/17 17 | // Prerequisite software packages: TNT, PCL 18 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 19 | 20 | #include 21 | #include 22 | #include "TNT/tnt.h" 23 | #include "LSDRaster.hpp" 24 | #include "LSDShapeTools.hpp" 25 | // PCL 26 | #include 27 | #include 28 | #include 29 | #include 30 | // liblas 31 | using namespace std; 32 | using namespace TNT; 33 | 34 | #ifndef LSDCloudRaster_H 35 | #define LSDCloudRaster_H 36 | 37 | /// @brief This code houses the LSDCloudRaster object, designed to create clouds from 38 | /// raster objects 39 | /// @author DTM, FJC 40 | /// @date 28/03/17 41 | class LSDCloudRaster 42 | { 43 | public: 44 | // Assignment operator. 45 | LSDCloudRaster& operator=(const LSDCloudRaster& cloud_object); 46 | 47 | LSDCloudRaster() { create(); } 48 | ///@brief create an LSDCloud from a raster. 49 | /// 50 | LSDCloudRaster(LSDRaster& raster) { create(raster); } 51 | 52 | ///@brief create an LSDCloud from a PointData object (see LSDShapeTools module) 53 | LSDCloudRaster(PointData& point_data, LSDRaster& raster) { create(point_data,raster); } 54 | 55 | LSDCloudRaster(int n_pts, float x_min, float x_max, float y_min, float y_max, float x_offset, float y_offset, pcl::PointCloud::Ptr cloud, const double resolution) 56 | { create( n_pts, x_min, x_max, y_min, y_max, x_offset, y_offset, cloud, resolution); } 57 | 58 | 59 | // get functions 60 | // these get data elements 61 | int get_NPts() const {return NPts;} 62 | float get_XMin() const { return XMin; } 63 | float get_YMin() const { return YMin; } 64 | float get_XMax() const { return XMax; } 65 | float get_YMax() const { return YMax; } 66 | float get_XOffset() const { return XOffset; } 67 | float get_YOffset() const { return YOffset; } 68 | pcl::PointCloud::Ptr get_theCloud() const { return theCloud; } 69 | float get_OctreeResolution() const { return OctreeResolution; } 70 | 71 | float get_point_x(int index) { return theCloud->points[index].x; } 72 | float get_point_y(int index) { return theCloud->points[index].y; } 73 | 74 | /// @brief Read in data from an LSDRaster into a LSDCloud object 75 | /// 76 | /// @details The point cloud is also structured in an octree for rapid spatial 77 | /// querying. Uses the PCL library (www.poinclouds.org). 78 | /// @param LSDRaster -> raster to convert to a LSDCloud 79 | /// @author DTM 80 | /// @date 18/02/2014 81 | void raster_to_cloud(LSDRaster& raster); 82 | 83 | /// @brief Read in data from a PointData (LSDShapeTools) into a LSDCloud 84 | /// 85 | /// @details The point cloud is also structured in an octree for rapid spatial 86 | /// querying. Uses the PCL library (www.poinclouds.org). 87 | /// @param PointData -> x,y coordinate strucure to load into cloud 88 | /// @param LSDRaster -> raster used as spatial reference frame 89 | /// @author DTM 90 | /// @date 11/04/2014 91 | void PointData_to_cloud(PointData& point_data, LSDRaster& raster); 92 | ///--------------------------------------------------------------------------- 93 | /// SEARCH TOOLS 94 | 95 | /// @brief Conducts a focal search (in xy plane), to find all points within 96 | /// defined search radius 97 | /// 98 | /// @details Points are arranged according to proximity to the query point 99 | /// @param float -> the x coordinate of the query point 100 | /// @param float -> the y coordinate of the query point 101 | /// @param float -> the search radius 102 | /// @param vector -> the values associated with the returned points 103 | /// @param vector -> the indexes associated with the returned points 104 | /// @param vector -> the squared distance of the returned points from the query point 105 | /// @author DTM 106 | /// @date 18/02/2014 107 | void RadiusSearch2D(float searchPoint_x, float searchPoint_y, float searchRadius, 108 | vector& pointValues, vector& pointIndex, vector& pointSquaredDistance); 109 | /// @brief Conducts a focal search (in the xy plane), to find the nearest K 110 | /// points 111 | /// 112 | /// @details Points are arranged according to proximity to the query point 113 | /// @param float -> the x coordinate of the query point 114 | /// @param float -> the y coordinate of the query point 115 | /// @param int -> the number of points to find 116 | /// @param vector -> the values associated with the returned points 117 | /// @param vector -> the indexes associated with the returned points 118 | /// @param vector -> the squared distance of the returned points from the query point 119 | /// @author DTM 120 | /// @date 18/02/2014 121 | void NearestNeighbourSearch2D(float searchPoint_x, float searchPoint_y, int K, 122 | vector& pointValues, vector& pointIndex, vector& pointSquaredDistance); 123 | 124 | 125 | protected: 126 | 127 | pcl::PointCloud::Ptr theCloud; 128 | 129 | // Octree spatial structure 130 | double OctreeResolution; 131 | pcl::octree::OctreePointCloudSearch *cloudOctree; 132 | 133 | // GEOREFERENCING 134 | // bounding box of point cloud 135 | float XMin; 136 | float YMin; 137 | float XMax; 138 | float YMax; 139 | // origin shift 140 | float XOffset; 141 | float YOffset; 142 | 143 | // metadata 144 | int NPts; 145 | 146 | private: 147 | void create(); 148 | void create(LSDRaster& raster); 149 | void create(int n_pts, float x_min, float x_max, float y_min, float y_max, 150 | float x_offset, float y_offset, pcl::PointCloud::Ptr cloud, const double resolution); 151 | void create(PointData& point_data, LSDRaster& raster); 152 | }; 153 | 154 | #endif 155 | -------------------------------------------------------------------------------- /src/LSDFileTools.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "LSDFileTools.hpp" 6 | using namespace std; 7 | 8 | 9 | #ifndef FileTools_CPP 10 | #define FileTools_CPP 11 | 12 | bool DoesFileExist(string filename) 13 | { 14 | bool WellDoesIt = false; 15 | 16 | struct stat sb; 17 | 18 | if (stat(filename.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)) 19 | { 20 | WellDoesIt = true; 21 | } 22 | return WellDoesIt; 23 | } 24 | 25 | bool DoesFileExist(string path, string fname) 26 | { 27 | bool WellDoesIt = false; 28 | 29 | string filename = path+fname; 30 | 31 | struct stat sb; 32 | 33 | if (stat(filename.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)) 34 | { 35 | WellDoesIt = true; 36 | } 37 | return WellDoesIt; 38 | } 39 | 40 | bool DoesDirectoryExist(string dirname) 41 | { 42 | bool WellDoesIt = false; 43 | 44 | struct stat sb; 45 | 46 | if (stat(dirname.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) 47 | { 48 | WellDoesIt = true; 49 | } 50 | return WellDoesIt; 51 | } 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/LSDFileTools.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | 6 | #ifndef FileTools_HPP 7 | #define FileTools_HPP 8 | 9 | // These functions check to see if a file or a directory exists 10 | bool DoesFileExist(string filename); 11 | bool DoesFileExist(string path, string fname); 12 | bool DoesDirectoryExist(string dirname); 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/LSDGrainMatrix.cpp: -------------------------------------------------------------------------------- 1 | /// LSDGrainMatrix.cpp 2 | /// 3 | /// IMPLEMENTATION FILE 4 | 5 | /* 6 | * SUMMARY 7 | * 8 | * LSDGrainMatrix is a class that defines an object to store data 9 | * about the surface and subsurface layers of raster or catchment. 10 | * It stores the grainsize fractions (of n fractions) for a given number 11 | * of surface and n subsurface layers. Be warned it is quite a large object 12 | * if you wish to define multiple fractions and multiple 13 | * subsurface layers! 14 | * 15 | * @author Declan Valters 16 | * @date 2016 17 | * University of Manchester 18 | * @contact declan.valters@manchester.ac.uk 19 | * @version 0.01 20 | * 21 | * Released under the GNU v2 Public License 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include // For the printing vector method 32 | 33 | #include // For fatal errors 34 | 35 | // Only for the debug macro 36 | #include 37 | 38 | 39 | #include "LSDGrainMatrix.hpp" 40 | 41 | #ifndef LSDGrainMatrix_CPP 42 | #define LSDGrainMatrix_CPP 43 | 44 | /*void LSDGrainMatrix::create() 45 | { 46 | std::cout << "You are trying to create an LSDGrainMatrix object with no supplied files or parameters." << std::endl << "Exiting..." << std::endl; 47 | exit(EXIT_FAILURE); 48 | }*/ 49 | 50 | void LSDGrainMatrix::create(int imax, int jmax, int NoDataVal, int G_MAX) 51 | { 52 | NRows = imax; // +2? -check in LSDCatchmentModel 53 | NCols = jmax; 54 | NoData = NoDataVal; 55 | GrainFracMax = G_MAX; 56 | std::cout << "Initialised a Grain Matrix..." << std::endl; 57 | } 58 | 59 | void LSDGrainMatrix::write_grainMatrix_to_ascii_file(std::string filename, 60 | std::string fname_extension) 61 | { 62 | std::string string_filename; 63 | std::string dot = "."; 64 | string_filename = filename + dot + fname_extension; 65 | std::cout << "The graindata filename is: " << string_filename << std::endl; 66 | 67 | if (fname_extension == "asc") 68 | { 69 | // Open a grain data file 70 | std::ofstream data_out(string_filename.c_str()); 71 | 72 | if( data_out.fail() ) 73 | { 74 | std::cout << "\n ERREUR FATALE!!!: Unable to write to " << string_filename \ 75 | << std::endl; 76 | exit(EXIT_FAILURE); 77 | } 78 | 79 | for(int i=1; i<=NRows; ++i) 80 | { 81 | for(int j=1; j<=NCols; ++j) 82 | { 83 | //std::cout << rasterIndex[i][j] << ", " << NoData << std::endl; 84 | if (rasterIndex[i][j] != NoData) 85 | { 86 | // Write the first part of the output file line (x,y location and index) 87 | data_out << i << " " << j << " " << rasterIndex[i][j] << " "; 88 | 89 | // Now write the Surface Grain bit 90 | for (int inc=0; inc<= GrainFracMax; inc++) 91 | { 92 | //std::cout << rasterIndex[i][j] << std::endl; 93 | data_out << grainData[rasterIndex[i][j]][inc] << " "; 94 | } 95 | 96 | // Now write the subsurface grain fractions 97 | for(int z=0; z<=9; z++) // Loop through subsurface layers... 98 | { 99 | for(int inc=0; inc<=(GrainFracMax-2); inc++) 100 | { 101 | data_out << strataData[rasterIndex[i][j]][z][inc] << " "; 102 | } 103 | } 104 | data_out << std::endl; 105 | } 106 | 107 | } 108 | } 109 | data_out.close(); 110 | } 111 | 112 | else 113 | { 114 | std::cout << "You did not enter and approprate extension!" << std::endl 115 | << "You entered: " << fname_extension << ", options are: asc" << std::endl; 116 | exit(EXIT_FAILURE); 117 | } 118 | } 119 | 120 | #endif 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /src/LSDGrainMatrix.hpp: -------------------------------------------------------------------------------- 1 | /// LSDGrainMatrix.hpp 2 | /// HEADER FILE 3 | 4 | /* 5 | * SUMMARY 6 | * 7 | * LSDGrainMatrix is a class that defines an object to store data 8 | * about the surface and subsurface layers of raster or catchment. 9 | * It stores the grainsize fractions (of n fractions) for a given number 10 | * of surface and n subsurface layers. Be warned it is quite a large object 11 | * if you wish to define multiple fractions and multiple 12 | * subsurface layers! 13 | * 14 | * @author Declan Valters 15 | * @date 2016 16 | * University of Manchester 17 | * @contact declan.valters@manchester.ac.uk 18 | * @version 0.01 19 | * 20 | * Released under the GNU v2 Public License 21 | * 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "TNT/tnt.h" 28 | 29 | #ifndef LSDGrainMatrix_H 30 | #define LSDGrainMatrix_H 31 | 32 | /// @brief This class is used primarily for the LSDCatchmentModel, to package up data 33 | /// about the stratigraphy and grain fraction data into neat objects. 34 | class LSDGrainMatrix 35 | { 36 | public: 37 | friend class LSDRaster; 38 | /* 39 | LSDGrainMatrix() 40 | { 41 | create(); //throws an error -- we don't want an empty object 42 | } 43 | */ 44 | /* 45 | /// Create a GrainMatrix object by reading in a file 46 | LSDGrainMatrix(std::string fname, std::string fname_extension) 47 | { 48 | create(fname, fname_extension); 49 | } 50 | */ 51 | /// Create a GrainMatrix object from references to arrays (in LSDCatchmentModel, though needn't be this object) 52 | LSDGrainMatrix( int imax, int jmax, int NoDataVal, int G_MAX, 53 | TNT::Array2D& indexes, 54 | TNT::Array2D& graindatas, 55 | TNT::Array3D& stratadatas) 56 | : rasterIndex(indexes), grainData(graindatas), strataData(stratadatas) 57 | { 58 | create(imax, jmax, NoDataVal, G_MAX); 59 | } 60 | 61 | /// Writes the GrainMatrix object to an output text file (Warning: large file!) 62 | void write_grainMatrix_to_ascii_file(std::string filename, std::string fname_extension); 63 | 64 | protected: 65 | TNT::Array2D& rasterIndex; 66 | TNT::Array2D& grainData; 67 | TNT::Array3D& strataData; 68 | 69 | int NCols; 70 | int NRows; 71 | int NoData; 72 | int GrainFracMax; 73 | 74 | private: 75 | //void create(); 76 | //void create(std::string fname, std::string fname_extension); 77 | void create(int imax, int jmax, int NoDataVal, int G_MAX); 78 | 79 | }; 80 | 81 | 82 | 83 | #endif // LSDGRAINMATRIX_HPP 84 | -------------------------------------------------------------------------------- /src/LSDMatrix.hpp: -------------------------------------------------------------------------------- 1 | /// LSDMatrix 2 | /// 3 | /// LSDMatrix is a basic, simple matrix class designed to store elements 4 | /// contiguously in memory. No fancy tools (matrix algebra etc). 5 | /// 6 | /// Experimental use! 7 | /// 8 | /// @author DAV, 2016 9 | 10 | #ifndef LSDMATRIX_HPP 11 | #define LSDMATRIX_HPP 12 | 13 | 14 | // http://www.graphics.cornell.edu/~martin/docs/c++-faq/freestore-mgmt.html#[16.15] 15 | // Class Template version from the C++FAQ 16 | // I think this is my favourite 17 | /// @brief Simple, barebones, matrix class with dimensions that can be set at run time, 18 | /// array is allocated contiguously in memory. 19 | template 20 | class LSDMatrix2D 21 | { 22 | public: 23 | LSDMatrix2D(unsigned rows, unsigned ncols); 24 | 25 | // For size being zero, we should throw error 26 | class BadSize { }; 27 | 28 | // Law of big 3 29 | ~LSDMatrix2D(); 30 | LSDMatrix2D(const LSDMatrix2D& m); 31 | LSDMatrix2D& operator= (const LSDMatrix2D& m); 32 | 33 | // Array access methods to get element with (i,j) notation 34 | T& operator() (unsigned i, unsigned j); 35 | const T& operator() (unsigned i, unsigned j) const; 36 | 37 | // Throw bounds violation if i, j too big 38 | class BoundsViolation { }; 39 | 40 | private: 41 | T* data_; 42 | unsigned nrows_, ncols_; 43 | }; 44 | 45 | // Access matrix elements with m(i,j) notation 46 | template 47 | inline T& LSDMatrix2D::operator() (unsigned row, unsigned col) 48 | { 49 | if (row >= nrows_ || col >= ncols_) throw BoundsViolation(); 50 | return data_[row*ncols_ + col]; 51 | } 52 | 53 | // Access matrix elements with m(i,j) notation (constatnt) 54 | template 55 | inline const T& LSDMatrix2D::operator() (unsigned row, unsigned col) const 56 | { 57 | if (row >= nrows_ || col >= ncols_) throw BoundsViolation(); 58 | return data_[row*ncols_ + col]; 59 | } 60 | 61 | // Declare matrix 62 | template 63 | inline LSDMatrix2D::LSDMatrix2D(unsigned rows, unsigned ncols) 64 | : data_ (new T[nrows * ncols]), 65 | nrows_ (nrows), 66 | ncols_ (ncols) 67 | { 68 | if (nrows == 0 || ncols == 0) 69 | throw BadSize(); 70 | } 71 | 72 | // Clean up after we're done with our matrix! 73 | template 74 | inline LSDMatrix2D::~LSDMatrix2D() 75 | { 76 | delete[] data_; 77 | } 78 | 79 | 80 | // OTHER EXAMPLES 81 | // http://stackoverflow.com/a/28841507/1953517 82 | class LSDArray2D 83 | { 84 | int* array; 85 | int m_width; 86 | public: 87 | LSDArray2D( int w, int h ) 88 | :m_width( w ), array( new int[ w * h ] ) {} 89 | 90 | ~LSDArray2D() { delete[] array; } 91 | 92 | int at( int x, int y ) 93 | const { return array[ index( x, y ) ]; } 94 | 95 | protected: 96 | int index( int x, int y ) 97 | const { return x + m_width * y; } 98 | 99 | }; 100 | 101 | 102 | // http://stackoverflow.com/a/32279494/1953517 103 | #include 104 | 105 | class LSDGrid2D 106 | { 107 | size_t _rows; 108 | size_t _columns; 109 | std::unique_ptr data; 110 | 111 | public: 112 | 113 | LSDGrid2D(size_t rows, size_t columns) 114 | : _rows{rows}, _columns{columns}, data{std::make_unique(rows * columns)} { 115 | } 116 | 117 | 118 | size_t rows() const { 119 | return _rows; 120 | } 121 | 122 | size_t columns() const { 123 | return _columns; 124 | } 125 | 126 | int * operator[](size_t row) { 127 | return row * _columns + data.get(); 128 | } 129 | 130 | }; 131 | 132 | 133 | 134 | 135 | // Example from the C++ cookbook 136 | // Require recipe 11.12! 137 | #include 138 | #include 139 | #include 140 | 141 | template 142 | class LSDMatrix 143 | { 144 | public: 145 | typedef Value_T value_type; 146 | typedef LSDMatrix self; 147 | typedef value_type* iterator; 148 | typedef const value_type* const_iterator; 149 | typedef Value_T* row_type; 150 | typedef stride_iter col_type; // need to implement stride iter! 151 | typedef const value_type* const_row_type; 152 | typedef stride_iter const_col_type; 153 | 154 | // CONSTRUCTORS 155 | LSDMatrix() : nrows(0), ncols(0, m() { } 156 | 157 | LSDMatrix(int r, int c) 158 | : nrows(r), ncols(c), m(r*c) { } 159 | 160 | LSDMatrix(const self& x) 161 | : m(x.m), nrows(x.rows), ncols(x.cols) { } 162 | 163 | template 164 | explicit LSDMatrix(const valarray & x) 165 | : m(x.size() + 1), nrows(x.size()), ncols(1) 166 | { 167 | for(int i=0; i 175 | explicit LSDMatrix(const LSDMatrix& x) 176 | : m(x.size() + 1), nrows(x.rows), ncols(x.cols) 177 | { 178 | copy(x.begin(), x.end(), m.begin()); 179 | } 180 | 181 | // Public Functions 182 | int rows() const { return nrows; } 183 | int cols() const { return ncols; } 184 | int size() const { return nrows * ncols; } 185 | 186 | // Element access 187 | row_type row_begin(int n) 188 | { 189 | return &m[n * ncols]; 190 | } 191 | 192 | row_type row_end 193 | 194 | 195 | }; 196 | 197 | #endif // LSDMATRIX_HPP 198 | 199 | -------------------------------------------------------------------------------- /src/LSDModelDriver.hpp: -------------------------------------------------------------------------------- 1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2 | // 3 | // LSDModelDriver 4 | // Land Surface Dynamics Model(s) Driver 5 | // 6 | // This object parses parameter files and drives the models: 7 | // 8 | // LSDRasterModel 9 | // LSDCatchmentModel (coming soon to a repository near you) 10 | // 11 | // Its purpose is to stop having to write a bunch of .cpp driver functions and instead 12 | // be able to write a parameter files without compiling 13 | // 14 | // Developed by: 15 | // Simon M. Mudd 16 | // Martin D. Hurst 17 | // David T. Milodowski 18 | // Stuart W.D. Grieve 19 | // Declan A. Valters 20 | // Fiona Clubb 21 | // 22 | // Copyright (C) 2014 Simon M. Mudd 2014 23 | // 24 | // Developer can be contacted by simon.m.mudd _at_ ed.ac.uk 25 | // 26 | // Simon Mudd 27 | // University of Edinburgh 28 | // School of GeoSciences 29 | // Drummond Street 30 | // Edinburgh, EH8 9XP 31 | // Scotland 32 | // United Kingdom 33 | // 34 | // This program is free software; 35 | // you can redistribute it and/or modify it under the terms of the 36 | // GNU General Public License as published by the Free Software Foundation; 37 | // either version 2 of the License, or (at your option) any later version. 38 | // 39 | // This program is distributed in the hope that it will be useful, 40 | // but WITHOUT ANY WARRANTY; 41 | // without even the implied warranty of 42 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 43 | // See the GNU General Public License for more details. 44 | // 45 | // You should have received a copy of the 46 | // GNU General Public License along with this program; 47 | // if not, write to: 48 | // Free Software Foundation, Inc., 49 | // 51 Franklin Street, Fifth Floor, 50 | // Boston, MA 02110-1301 51 | // USA 52 | // 53 | ///=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 54 | /// 55 | /// This object is written by 56 | /// @author Simon M. Mudd, University of Edinburgh 57 | /// @author David T. Milodowski, University of Edinburgh 58 | /// @author Martin D. Hurst, British Geological Survey 59 | /// @author Fiona Clubb, University of Edinburgh 60 | /// @author Stuart Grieve, University of Edinburgh 61 | /// @author James Jenkinson, University of Edinburgh 62 | /// @author Declan Valters, University of Manchester 63 | /// 64 | ///=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 65 | /// 66 | /// Version 0.0.1 2015-01-15 67 | ///=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 68 | 69 | #include 70 | 71 | #include "LSDAnalysisDriver.hpp" 72 | #include "LSDRasterModel.hpp" 73 | #include "LSDCatchmentModel.hpp" 74 | 75 | #ifndef LSDModelDriver_H 76 | #define LSDModelDriver_H 77 | 78 | 79 | 80 | /// @brief This is a class to manage running LSDTopoTools. It parses a parameter 81 | /// file and then manages running of analyses. 82 | /// @details The intention of this object is to run analyses via parameter 83 | /// files and not through numerous compiled driver functions. We eventually 84 | /// will want some kind of 'recorder' so that any time this object 85 | /// runs an analysis it gives a full report of what analyses were run so that 86 | /// results are reproducable 87 | class LSDModelDriver : public LSDCatchmentModel, LSDRasterModel //(not sure about this - perhaps keep them totally separate for now?) 88 | { 89 | public: 90 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 91 | // 92 | // Constructors 93 | // 94 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 95 | /// @brief The default constructor. 96 | /// @details this asks for a pathname and a filename of the parameter file 97 | /// It then opens the paramter file and ingests the information 98 | /// @author DAV 99 | /// @date 2015-01-16 100 | LSDModelDriver() 101 | { 102 | create(); 103 | } 104 | 105 | /// @brief this constructor just reads the param file given by the path and 106 | /// filename. You must give the parameter file extension! 107 | /// @param pname the pathname to the parameter file 108 | /// @param fname the filename of the parameter file !!INCLUDING EXTENSION!! 109 | /// @author DAV 110 | /// @date 2015-01-16 111 | LSDModelDriver(string pname, string pfname) 112 | { 113 | create(pname, pfname); 114 | } 115 | 116 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 117 | // 118 | // Main drivers of reading, computation and writing of data 119 | // 120 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 121 | /// @brief This is the main function for parsing the parameter file 122 | /// @param pathname the path to the paramter file 123 | /// @param param_fname the name of the parameter file 124 | /// @author SMM 125 | /// @date 29/07/2014 126 | void ingest_data(string pname, string p_fname); 127 | 128 | void select_model_from_model_map(); 129 | 130 | void run_LSDCatchmentModel_components(); 131 | 132 | void run_LSDRasterModel_components(); 133 | 134 | protected: 135 | /// the path to the datafiles 136 | string pathname; 137 | 138 | /// the name of the parameter file 139 | string param_fname; 140 | 141 | /// Extension for reading DEMs. Correspondence with write extensions is checked 142 | string dem_read_extension; 143 | 144 | /// Extension for writing DEMs. Correspondence with read extensions is checked 145 | string dem_write_extension; 146 | 147 | /// Path to files being written. Default is pathname 148 | string write_path; 149 | 150 | /// file prefix of files to be written. Default is the param name prefix 151 | string write_fname; 152 | 153 | /// Path to files being read. Default is pathname 154 | string read_path; 155 | 156 | /// file prefix of files to be written. Default is the param name prefix 157 | string read_fname; 158 | 159 | private: 160 | 161 | void check_pathname_for_slash(); 162 | 163 | /// This holds names of the different model cores that can be run from the 164 | /// Model Driver 165 | std::map model_map; 166 | 167 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 168 | // 169 | // CREATE FUNCTIONS 170 | // 171 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 172 | 173 | /// @brief default create function 174 | /// @details this asks for a pathname and a filename of the parameter file 175 | /// It then opens the paramter file and ingests the information 176 | /// @author DAV 177 | /// @date 2015-01-16 178 | void create(); 179 | 180 | /// @brief create function 181 | /// @param pname the pathname to the parameter file 182 | /// @param fname the filename of the parameter file !!INCLUDING EXTENSION!! 183 | /// @author DAV 184 | /// @date 201-01-16 185 | void create(string pname, string fname); 186 | 187 | 188 | 189 | }; 190 | 191 | 192 | #endif 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /src/LSDNetCDFTools.cpp: -------------------------------------------------------------------------------- 1 | // LSDNetCDFTools.cpp 2 | 3 | /// Note: you need to compile with -lnetcdf and -lnetcdf_cxx4 flags 4 | /// You will need the need the netCDF-4 C++ libraries installed 5 | /// Most Linux package managers will install this for you using 6 | /// yum, dnf, or apt-get. 7 | 8 | /// A tool for reading netCDF-4 files into LSDTopoTools 9 | /// 10 | /// NetCDF (The network common data format is a file format for storing 11 | /// multivariate climate, atmospheric, etc. data. (Although it can be used to store 12 | /// any type of gridded data. You could use it to store states of topography through 13 | /// time, for example.) 14 | 15 | /// Full documentation of the netCDF C++ API can be found at: 16 | /// http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-cxx 17 | /// 18 | /// @author DAV 19 | /// @date 2016-11-05 20 | 21 | #include 22 | #include 23 | #include "TNT/tnt.h" 24 | 25 | using namespace netCDF; 26 | using namespace netCDF::exceptions; 27 | 28 | // Return this in event of a problem. 29 | static const int NC_ERR = 2; 30 | 31 | // Originally had it as a class but not much point at this stage 32 | // just make it a namespace instead 33 | namespace LSDNetCDFTools 34 | { 35 | 36 | /// @brief Reads in a netCDF field and writes it into 37 | /// a TNT array 1D. 38 | /// @return An error code, (0 for success, NC_ERR for failure) 39 | /// @details Template allows to specify different TNT array data types 40 | /// e.g. double, float, int etc. 41 | /// @param reference to a tnt::array1d, the name of a netcdf file to read 42 | /// @note 1d not yet implemented...see 2d. 43 | template 44 | int read_tnt_array1d(TNT::Array1D*const tnt_array); 45 | 46 | /// @brief Reads in a netCDF field and writes it into 47 | /// a TNT array 2D. 48 | /// @return An error code, (0 for success, NC_ERR for failure) 49 | /// @details Template allows to specify different TNT array data types 50 | /// e.g. double, float, int etc. 51 | /// @param reference to a tnt::array2d, the name of a netcdf file to read 52 | template 53 | int read_tnt_array2d(TNT::Array2D*const tnt_array, std::string nc_file); 54 | // The pointer to the tnt array is constant, but not the actual array itself 55 | // i.e. we can change the array thtough the pointer, but ensure the pointer 56 | // remains constant and cannot be changed to point to something else, which would be 57 | // a bad idea... 58 | 59 | /// @brief Reads in a netCDF field and writes it into 60 | /// a TNT array 3D. 61 | /// @return An error code, (0 for success, NC_ERR for failure) 62 | /// @details Template allows to specify different TNT array data types 63 | /// e.g. double, float, int etc. 64 | /// @param reference to a tnt::array3d, the name of a netcdf file to read 65 | template 66 | int read_tnt_array3d(TNT::Array3D*const tnt_array, std::string nc_file); 67 | 68 | //=-=-=-=-=-=-=-=-= 69 | // IMPLEMENTATIONS 70 | //=-=-=-=-=-=-=-=-= 71 | 72 | template 73 | int read_tnt_array3d(TNT::Array3D*const tnt_array, std::string nc_file) 74 | { 75 | int n_timesteps = tnt_array->dim1(); 76 | int rows = tnt_array->dim2(); 77 | int cols = tnt_array->dim3(); 78 | 79 | std::cout << "Timesteps: " << n_timesteps << ", " << "Rows: " << rows << 80 | ", " << "Cols: " << cols << std::endl; 81 | 82 | // Should introduce some error checking here to make sure sure 83 | // the dims in the netcdf file match the referenced array passed... 84 | try 85 | { 86 | // Open the file. 87 | NcFile dataFile(nc_file, NcFile::read); 88 | 89 | // Get the latitude and longitude variables and read data. 90 | NcVar latVar, lonVar; 91 | 92 | // latVar = dataFile.getVar("latitude"); 93 | // if(latVar.isNull()) return NC_ERR; 94 | // lonVar = dataFile.getVar("longitude"); 95 | // if(lonVar.isNull()) return NC_ERR; 96 | // lonVar.getVar(lons); 97 | // latVar.getVar(lats); 98 | 99 | NcVar presVar; 100 | presVar = dataFile.getVar("pressure"); 101 | if(presVar.isNull()) return NC_ERR; 102 | 103 | // Read in data to array 104 | // Works because the elements are contiguous 105 | // in memory. 106 | presVar.getVar(tnt_array[0][0][0]); 107 | 108 | for (size_t timestep = 0; timestep < n_timesteps; timestep++) 109 | { 110 | //for (int timestep = 0; timestep < NREC; timestep++) 111 | std::cout << "TIMESTEP: " << timestep<< std::endl; 112 | for (int row = 0; row < rows; row++) 113 | { 114 | for (int col = 0; col < cols; col++) 115 | { 116 | // derefernce our pointer to array with the (*ptr)[][] notation... 117 | std::cout << (*tnt_array)[timestep][row][col] << " "; 118 | //if((*tnt_array)[rec][lat][lon] != (float) (SAMPLE_PRESSURE + i)) return NC_ERR; 119 | } 120 | std::cout << std::endl; 121 | } 122 | std::cout << std::endl; 123 | 124 | } // next record 125 | 126 | // The file is automatically closed by the destructor. This frees 127 | // up any internal netCDF resources associated with the file, and 128 | // flushes any buffers. 129 | 130 | std::cout << "*** SUCCESS reading example file " << nc_file << std::endl; 131 | return 0; 132 | 133 | } 134 | catch(NcException& e) 135 | { 136 | e.what(); 137 | std::cout<<"FAILURE**************************"< 143 | int read_tnt_array1d(TNT::Array1D*const tnt_array) 144 | { 145 | //1d should be easy 146 | } 147 | 148 | template 149 | int read_tnt_array2d(TNT::Array2D*const tnt_array, std::string nc_file) 150 | { 151 | int NX = tnt_array->dim1(); 152 | int NY = tnt_array->dim2(); 153 | 154 | std::cout << "Rows: " << NX << ", " << "Cols: " << NY << std::endl; 155 | 156 | try 157 | { 158 | // This is a C-style array. 159 | // We tend not to use these in LSDTopoTools 160 | // but typically used in netCDF. 161 | // int dataIn[NX][NY]; 162 | 163 | // This is a TNT (Template Numerical Toolkit) 164 | // 2D array (allocated at runtime) 165 | //tnt_array(NX,NY,0); 166 | 167 | // Open the file for read access 168 | NcFile dataFile(nc_file, NcFile::read); 169 | 170 | // Retrieve the variable named "data" 171 | NcVar data = dataFile.getVar("data"); 172 | if(data.isNull()) return NC_ERR; 173 | 174 | // Ingest the data into the array 175 | // We pass a reference to the first element of 176 | // the TNT array [0][0]. getVar writes in the values. 177 | data.getVar(tnt_array[0][0]); 178 | 179 | // Note: with a C-style array you would do this: 180 | // data.getVar(dataIn) 181 | // Since C arrays are already pointers to memory. 182 | 183 | // Check the values 184 | for (int i = 0; i < NX; i++) 185 | { 186 | for (int j = 0; j < NY; j++) 187 | { 188 | // Check that we haven't gone out of bounds... 189 | //if (*tnt_array[i][j] != i * NY + j) return NC_ERR; 190 | //else 191 | { 192 | std::cout << (*tnt_array)[i][j] << " "; 193 | } 194 | } 195 | std::cout << std::endl; 196 | } 197 | 198 | // The netCDF file is automatically closed by the NcFile destructor 199 | std::cout << "*** SUCCESS reading example file " << nc_file << std::endl; 200 | 201 | return 0; 202 | } 203 | catch(NcException& e) 204 | { 205 | e.what(); 206 | std::cout<<"FAILURE*************************************"<< std::endl; 207 | return NC_ERR; 208 | } 209 | } 210 | } 211 | 212 | // Test. 213 | 214 | //using namespace LSDNetCDFTools; 215 | 216 | int main() 217 | { 218 | // Test reading in a 2D netcdf file 219 | TNT::Array2D myArray2D(6,12, 0); 220 | 221 | LSDNetCDFTools::read_tnt_array2d(&myArray2D, "simple_xy.nc"); 222 | 223 | // Test reading in a 3D (i.e. one var + timestep) 224 | TNT::Array3D myArray3D(2, 6,12, 0.0); 225 | 226 | LSDNetCDFTools::read_tnt_array3d(&myArray3D, "pres_temp_3D.nc"); 227 | } 228 | -------------------------------------------------------------------------------- /src/LSDRainfallRunoff.cpp: -------------------------------------------------------------------------------- 1 | /// LSDRainfallRunoff.cpp 2 | 3 | /* 4 | * Used for various weather/storm generators, climate data interpolation 5 | * etc. 6 | * 7 | * Will use some of the interpolate routines in LSDSTatsTools. 8 | * 9 | * @author Declan Valters 10 | * @date 2014, 2015, 2016 11 | * University of Manchester 12 | * @contact declan.valters@manchester.ac.uk 13 | * @version 0.01 14 | * 15 | * Released under the GNU v2 Public License 16 | * 17 | */ 18 | 19 | #ifndef LSDRainfallRunoff_CPP 20 | #define LSDRainfallRunoff_CPP 21 | 22 | #include "LSDRainfallRunoff.hpp" 23 | #include "LSDRaster.hpp" 24 | 25 | void rainGrid::create() 26 | { 27 | std::cout << "You have tried to create an empty RainfallRunoff object. " << 28 | std::endl << "Please try again with some parameters" << 29 | std::endl; 30 | exit(EXIT_FAILURE); 31 | } 32 | 33 | void rainGrid::create(std::vector< std::vector >& rain_data, 34 | TNT::Array2D& hydroindex, 35 | int imax, int jmax, int current_rainfall_timestep, 36 | int rf_num) 37 | { 38 | // Creates a 2D object of rainfall data based on the extents of the 39 | // current model domain, and the rainfall timeseries. 40 | rainfallgrid2D = TNT::Array2D(imax+2, jmax+2, 0.0); 41 | 42 | // DEBUG 43 | if (rf_num == 1) 44 | { 45 | rainfallgrid2D = rain_data[current_rainfall_timestep][0]; // or [1]? 46 | return; 47 | } 48 | 49 | //std::cout << "HYDROINDEX DEBUG: " << std::endl; 50 | //std::cout << hydroindex.dim1() << ", " << hydroindex.dim2() << std::endl; 51 | // DAV addeded pragma for testing 08/2016 52 | #pragma omp parallel for 53 | for (int i=1; i& rain_data, int current_raindata_timestep, int imax, int jmax) 69 | { 70 | //Ingest from netcdf file 71 | rainfallgrid2D = TNT::Array2D(imax+2,jmax+2, 0.0); 72 | 73 | for (int i=1; i(imax +2, jmax +2, 0.000000001); 128 | jo_array = TNT::Array2D(imax +2, jmax +2, 0.000000001); 129 | j_mean_array = TNT::Array2D(imax +2, jmax +2, 0.0); 130 | old_j_mean_array = TNT::Array2D(imax +2, jmax +2, 0.0); 131 | new_j_mean_array = TNT::Array2D(imax +2, jmax +2, 0.0); 132 | 133 | // This is all that happens, use calculate_runoff() to fill in with proper values. 134 | 135 | } 136 | 137 | // Same as abouve but calculates values for runoff matrices given raingrid and a timestep 138 | // and other relevant params. 139 | void runoffGrid::create(int current_rainfall_timestep, int imax, int jmax, 140 | int rain_factor, double M, 141 | const rainGrid& current_rainGrid, 142 | const TNT::Array2D& elevations) 143 | { 144 | std::cout << "Creating a RUNOFF GRID OBJECT FROM RAINGRID..." << std::endl; 145 | // set arrays to relevant size for model domain 146 | j_array = TNT::Array2D(imax +2, jmax +2, 0.000000001); 147 | jo_array = TNT::Array2D(imax +2, jmax +2, 0.000000001); 148 | j_mean_array = TNT::Array2D(imax +2, jmax +2, 0.0); 149 | old_j_mean_array = TNT::Array2D(imax +2, jmax +2, 0.0); 150 | new_j_mean_array = TNT::Array2D(imax +2, jmax +2, 0.0); 151 | 152 | calculate_runoff(rain_factor, M, jmax, imax, current_rainGrid, elevations); 153 | } 154 | 155 | void runoffGrid::write_runoffGrid_to_raster_file(double xmin, 156 | double ymin, 157 | double cellsize, 158 | std::string RUNOFFGRID_FNAME, 159 | std::string RUNOFFGRID_EXTENSION) 160 | { 161 | // For checking purposes mainly. Writes grid to an ascii file so 162 | // I can see if the upscale or interpolate has worked correctly. 163 | int nrows = new_j_mean_array.dim1(); 164 | int ncols = new_j_mean_array.dim2(); 165 | 166 | int nodata = -9999; 167 | 168 | LSDRaster output_runoffgrid(nrows, ncols, xmin, ymin, cellsize, nodata, 169 | new_j_mean_array); 170 | output_runoffgrid.strip_raster_padding(); 171 | output_runoffgrid.write_double_raster(RUNOFFGRID_FNAME, RUNOFFGRID_EXTENSION); 172 | } 173 | 174 | 175 | void runoffGrid::calculate_runoff(int rain_factor, double M, int jmax, int imax, 176 | const rainGrid& current_rainGrid, 177 | const TNT::Array2D& elevations) 178 | { 179 | //std::cout << "calculate_runoff" << std::endl; 180 | // DAV addeded pragma for testing 08/2016 181 | #pragma omp parallel for 182 | for (int m=1; m -9999) 189 | { 190 | double local_rainfall_rate =0; 191 | double local_time_step=60; 192 | 193 | old_j_mean_array[m][n] = new_j_mean_array[m][n]; 194 | jo_array[m][n] = j_array[m][n]; 195 | 196 | // Variable M value would go here 197 | // if (variable_m_flag == true) { } 198 | 199 | 200 | if (current_rainGrid.get_rainfall(m, n) > 0) 201 | { 202 | //std::cout << "Rainfall is: " << current_rainGrid.get_rainfall(m, n) << std::endl; 203 | // Divide by 1000 to get m/hr, then 3600 for m/sec 204 | local_rainfall_rate = rain_factor * ((current_rainGrid.get_rainfall(m, n) 205 | / 1000) / 3600); 206 | } 207 | 208 | // If case is zero, we still need to calculate the amount of saturation decay 209 | // for this time step (TOPMODEL based) 210 | if (local_rainfall_rate == 0) 211 | { 212 | j_array[m][n] = jo_array[m][n] / (1 + ((jo_array[m][n] * local_time_step) / M)); 213 | 214 | new_j_mean_array[m][n] = M / local_time_step * 215 | std::log(1 + ((jo_array[m][n] * local_time_step) / M)); 216 | } 217 | 218 | // If there is some rain in this cell, we need to calculate how much 219 | // is runoff vs infiltrates (TOPMODEL based) 220 | if (local_rainfall_rate > 0) 221 | { 222 | //std::cout << "Cell Rainfall Rate is: " << local_rainfall_rate << std::endl; 223 | 224 | j_array[m][n] = local_rainfall_rate / (((local_rainfall_rate - jo_array[m][n]) / jo_array[m][n]) 225 | * std::exp((0 - local_rainfall_rate) * local_time_step / M) + 1); 226 | 227 | new_j_mean_array[m][n] = (M / local_time_step) 228 | * std::log(((local_rainfall_rate - jo_array[m][n]) + jo_array[m][n] 229 | * std::exp((local_rainfall_rate *local_time_step) 230 | / M)) / local_rainfall_rate); 231 | } 232 | 233 | // Don't want to have negative J_means! 234 | if (new_j_mean_array[m][n] < 0) 235 | { 236 | new_j_mean_array[m][n] = 0; 237 | } 238 | } 239 | } 240 | } 241 | } 242 | 243 | #endif 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /src/LSDRainfallRunoff.hpp: -------------------------------------------------------------------------------- 1 | // LSDRainfallRunoff.hpp 2 | // HEADER FILE 3 | 4 | /* 5 | * Used for various weather/storm generators, climate data interpolation 6 | * etc. 7 | * 8 | * Will use some of the interpolate routines in LSDSTatsTools. 9 | * 10 | * @author Declan Valters 11 | * @date 2014, 2015, 2016 12 | * University of Manchester 13 | * @contact declan.valters@manchester.ac.uk 14 | * @version 0.01 15 | * 16 | * Released under the GNU v2 Public License 17 | * 18 | */ 19 | 20 | #ifndef LSDRAINFALLRUNOFF_H 21 | #define LSDRAINFALLRUNOFF_H 22 | 23 | #include "TNT/tnt.h" 24 | #include "LSDStatsTools.hpp" // This contains some spline interpolation functions already 25 | 26 | /// @brief rainGrid is a class used to store and manipulate rainfall data. 27 | /// @detail It can be used to interpolate or downscale rainfall data from coarser 28 | /// resolutions/grid spacings. 29 | /// @author DAV 30 | class rainGrid 31 | { 32 | public: 33 | 34 | /// Default constructor -- throws an error. 35 | rainGrid() 36 | { 37 | create(); 38 | } 39 | 40 | /// Create a raingrid from the rainfall data vector, 41 | /// and the raster or model domain dimensions, for the 42 | /// current timestep only. Specify an interpolation method 43 | rainGrid(std::vector< std::vector >& rain_data, 44 | TNT::Array2D& hydroindex, 45 | int imax, int jmax, int current_rainfall_timestep, int rf_num) 46 | { 47 | //std::cout << "Creating a LSD rainGrid object from a rainfall timeseries and hydroindex..." \ 48 | // << std::endl; 49 | create(rain_data, hydroindex, imax, jmax, current_rainfall_timestep, rf_num); 50 | } 51 | 52 | /// Create rainGrid from interpolating between sparse points and x, y coord 53 | /// TODO 54 | 55 | /// Takes a 2D array of regular gridded rainfall and interpolates 56 | /// it according to a Bivariate Spline. Similar to sciPy's 57 | /// scipy.interpolate.RectBivariateSpline 58 | void interpolateRainfall_RectBivariateSpline(rainGrid& raingrid); 59 | 60 | /// Will take a 2D array of regular gridded rainfall and interpolates 61 | /// it based on a TRI-variate spline. I.e. interpolates based on an 62 | /// extra third variable which would be terrain in most cases (see 63 | /// Tait et al 2006, for example) 64 | void interpolateRainfall_RectTrivariateSpline(rainGrid& raingrid, 65 | const TNT::Array2D& elevation); 66 | 67 | /// Takes the rainfall data for a current timestep and 68 | /// reshapes it into a 2D array. 69 | void ReShapeRainfallData_2DArray(); 70 | 71 | /// Downscales the 2d rainfall array to a resampled, higher resolution 72 | /// array, with the same grid spacing, and dimensions as the model or 73 | /// raste rdomain. 74 | /// @note This is actually done by the create() function for now, but it 75 | /// should probably go in its own method. 76 | void downscaleRainfallData(); 77 | 78 | /// Writes the 2D upscaled and/or interpolated rainfall grid to 79 | /// a raster output file for checking. 80 | void write_rainGrid_to_raster_file(double xmin, double ymin, 81 | double cellsize, 82 | std::string RAINGRID_FNAME, 83 | std::string RAINGRID_EXTENSION); 84 | 85 | /// Getter for getting rainfall value 86 | double get_rainfall(int i, int j) const { return rainfallgrid2D[i][j]; } 87 | 88 | 89 | 90 | protected: 91 | 92 | /// For a single instance of a 2D rainfall grid, matching the dimensions of the 93 | /// model domain. 94 | TNT::Array2D rainfallgrid2D; 95 | /// Experimental - stores grids of rainfall data for every rainfall timestep: 96 | /// Warning - this could be a massive object! 97 | TNT::Array3D rainfallgrid3D; 98 | 99 | private: 100 | /// Returns an error, empty object pointless 101 | void create(); 102 | /// Initialises by converting rainfall data file into grid at same 103 | /// grid spacing as model (or raster) domain grid spacing. 104 | void create(std::vector >& rain_data, 105 | TNT::Array2D& hydroindex, 106 | int imax, int jmax, int current_rainfall_timestep, int rf_num); 107 | 108 | /// Creates a raingrid for the current timestep by extracting from the netCDF data file. 109 | /// TO DO 110 | void create(TNT::Array3D& rain_data, int current_raindata_timestep, int imax, int jmax); 111 | 112 | }; 113 | 114 | 115 | /// @brief Object for storing and calculating the saturation and hence 116 | /// surface runoff when using spatially 117 | /// variable rainfall input (j_mean, but 2D, i.e. j_mean_array[i][j], same as 118 | /// model 119 | /// @details This object treats runoff production as spatially variable at 120 | /// the same resolution as the model domain DEM. It calculates runoff separately 121 | /// for every grid cell, so is slightly different from the TOPMODEL formulation 122 | /// which divides the runoff response into zones with similar attributes. 123 | /// @author DAV 124 | class runoffGrid 125 | { 126 | public: 127 | 128 | /// Basic constructor -- initialises arrays to domain size. 129 | runoffGrid(int imax, int jmax) 130 | { 131 | create(imax, jmax); 132 | } 133 | 134 | /// Create a rainfallrunoffGrid from passing params and refs to params 135 | runoffGrid(int current_rainfall_timestep, int imax, int jmax, 136 | int rain_factor, double M, 137 | const rainGrid& current_rainGrid, 138 | const TNT::Array2D& elevations) 139 | { 140 | create(current_rainfall_timestep, imax, jmax, 141 | rain_factor, M, 142 | current_rainGrid, 143 | elevations); 144 | } 145 | 146 | //void calculate_catchment_water_inputs(); // Left this is CatchmentModel object for now 147 | // could be moved at later date, but we need reorganisation of classes. 148 | 149 | /// Calculates runoff and updates the rainfallrunoffGrid object accordingly 150 | /// Introduced to be able to create an empty runoff object and then later initialise it, 151 | /// or update an exisiting runoff grid for a new timestep, 152 | /// @params Takes a ref to a rainGrid object and the elevations array from LSDCatchmentModel 153 | void calculate_runoff(int rain_factor, double M, int jmax, int imax, 154 | const rainGrid ¤t_rainGrid, 155 | const TNT::Array2D& elevations); 156 | 157 | void write_runoffGrid_to_raster_file(double xmin, 158 | double ymin, 159 | double cellsize, 160 | std::string RUNOFFGRID_FNAME, 161 | std::string RUNOFFGRID_EXTENSION); 162 | 163 | // Getters for runoff variables 164 | double get_j(int m, int n) const { return j_array[m][n]; } 165 | double get_jo(int m, int n) const { return jo_array[m][n]; } 166 | double get_j_mean(int m, int n) const { return j_mean_array[m][n]; } 167 | double get_old_j_mean(int m, int n) const { return old_j_mean_array[m][n]; } 168 | double get_new_j_mean(int m, int n) const { return new_j_mean_array[m][n]; } 169 | 170 | /// Sets the value of j_mean when calculating the hydrograh 171 | /// @param m, n array indices, new value to set (double) 172 | void set_j_mean(int m, int n, double cell_j_mean) { j_mean_array[m][n] = cell_j_mean; } 173 | 174 | protected: 175 | TNT::Array2D j_array, jo_array, j_mean_array, old_j_mean_array, new_j_mean_array; 176 | 177 | private: 178 | void create(int imax, int jmax); 179 | void create(int current_rainfall_timestep, int imax, int jmax, 180 | int rain_factor, double M, 181 | const rainGrid& current_rainGrid, const TNT::Array2D& elevations); 182 | }; 183 | 184 | 185 | #endif // LSDWEATHERCLIMATETOOLS_H 186 | -------------------------------------------------------------------------------- /src/LSDRasterAggregator.hpp: -------------------------------------------------------------------------------- 1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2 | // 3 | // LSDRasterAggregator.hpp 4 | // Land Surface Dynamics RasterAggregator 5 | // 6 | // An object within the University 7 | // of Edinburgh Land Surface Dynamics group topographic toolbox 8 | // that is a very general object for managing aggregated raster calculations 9 | // 10 | // Developed by: 11 | // Simon M. Mudd 12 | // Martin D. Hurst 13 | // David T. Milodowski 14 | // Stuart W.D. Grieve 15 | // Declan A. Valters 16 | // Fiona Clubb 17 | // 18 | // Copyright (C) 2013 Simon M. Mudd 2013 19 | // 20 | // Developer can be contacted by simon.m.mudd _at_ ed.ac.uk 21 | // 22 | // Simon Mudd 23 | // University of Edinburgh 24 | // School of GeoSciences 25 | // Drummond Street 26 | // Edinburgh, EH8 9XP 27 | // Scotland 28 | // United Kingdom 29 | // 30 | // This program is free software; 31 | // you can redistribute it and/or modify it under the terms of the 32 | // GNU General Public License as published by the Free Software Foundation; 33 | // either version 2 of the License, or (at your option) any later version. 34 | // 35 | // This program is distributed in the hope that it will be useful, 36 | // but WITHOUT ANY WARRANTY; 37 | // without even the implied warranty of 38 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 39 | // See the GNU General Public License for more details. 40 | // 41 | // You should have received a copy of the 42 | // GNU General Public License along with this program; 43 | // if not, write to: 44 | // Free Software Foundation, Inc., 45 | // 51 Franklin Street, Fifth Floor, 46 | // Boston, MA 02110-1301 47 | // USA 48 | // 49 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include "LSDRaster.hpp" 55 | #include "LSDFlowInfo.hpp" 56 | using namespace std; 57 | 58 | #ifndef RasterAggregator_HPP 59 | #define RasterAggregator_HPP 60 | 61 | /// @brief A general object for holding several different raster layers 62 | class LSDRasterAggregator 63 | { 64 | public: 65 | 66 | /// @brief the default constructor. This doesn't do anything. 67 | LSDRasterAggregator() { create(); } 68 | 69 | /// @brief This constructor requires a filename 70 | /// @detail The filename and path point to files with the rasters 71 | /// @param path The path to the files 72 | /// @param file_prefix the prefix of the files 73 | /// @author SMM 74 | /// @date 10/02/2016 75 | LSDRasterAggregator( string path, string file_prefix) { create(path,file_prefix); } 76 | 77 | /// @brief This function load a csv file containing names of a DEMs and 78 | /// (possibly) other rasters 79 | /// @detail The first row of the file contains column headers and is ignored 80 | /// Thereafter you have two columns in each row, comma seperated, 81 | /// with the raster type as the first column and the raster filename 82 | /// (with full path) as the second. 83 | /// @param filename the name of the file 84 | /// @author SMM 85 | /// @date 10/02/2016 86 | void load_raster_filenames(string filename); 87 | 88 | /// @brief this function checks the existence and georeferencing of 89 | /// the rasters outlined in the file list 90 | /// @author SMM 91 | /// @date 10/02/2016 92 | void check_rasters(); 93 | 94 | /// @brief Prints the raster names and types to screen 95 | /// @detail you must have loaded the rasters first 96 | /// @author SMM 97 | /// @date 28/11/2018 98 | void print_raster_names_and_types_to_screen(); 99 | 100 | /// @brief You suply a vector of strings with raster types and this 101 | /// return true if all of those raster types are present in the raster list 102 | /// @param raster_types a vector of raster type strings 103 | /// @return a bool: true if all types are in the list, false if not 104 | /// @author SMM 105 | /// @date 08/12/2018 106 | bool check_raster_types(vector raster_types); 107 | 108 | /// @brief This computes the flux from each pixel in a raster 109 | /// @param raster_types a vector of raster type strings 110 | /// @return A raster of the fluxes 111 | /// @author SMM 112 | /// @date 13/12/2018 113 | LSDRaster create_flux_raster(vector raster_types); 114 | 115 | protected: 116 | 117 | /// the path to the cosmo data. Also used to print results 118 | string path; 119 | 120 | /// the prefix of the parameter files 121 | string param_name; 122 | 123 | /// A map for holding the different raster filenames 124 | /// The index into the raster filenames is the raster type. 125 | /// There are some commone raster types: 126 | /// DEM is the DEM 127 | /// ---more to come here--- 128 | map< string,string > raster_filenames; 129 | 130 | /// A map holding the parameter values. These are stored as strings 131 | /// and converted to the appropriate data type as needed 132 | map parameter_map; 133 | 134 | /// The minimum slope for the fill function 135 | float min_slope; 136 | 137 | /// The boundary conditions for flow info calculations 138 | vector boundary_conditions; 139 | 140 | private: 141 | 142 | /// @brief the empty create function 143 | void create(); 144 | 145 | /// @brief the create function used when calling a file 146 | /// @param the path to the file. Must have the "/" at the end 147 | /// @param file_prefix the prefix (without extension) of the parameter files 148 | /// @author SMM 149 | /// @date 10/02/2016 150 | void create(string path, string file_prefix); 151 | }; 152 | 153 | /// @brief A derived class that is used to compute erosion rates based on 154 | /// concentrations of in-situ cosmogenic nuclides such as 10Be and 26Al 155 | class LSDSedimentRouting: public LSDRasterAggregator 156 | { 157 | 158 | public: 159 | 160 | /// @brief This constructor requires a filename 161 | /// @detail The filename and path point to files with the rasters 162 | /// @param path The path to the files 163 | /// @param file_prefix the prefix of the files 164 | /// @author SMM 165 | /// @date 10/02/2016 166 | LSDSedimentRouting( string path, string file_prefix) { create(path,file_prefix); } 167 | 168 | /// @brief This checks for the parameter values specific to the sediment routing routines 169 | /// @author SMM 170 | /// @date 10/02/2016 171 | void check_parameter_values(); 172 | 173 | /// @brief Prints the parameter values to screen 174 | /// @author SMM 175 | /// @date 10/02/2016 176 | void print_parameter_values_to_screen(); 177 | 178 | // WILL NEED TO WORK ON THIS 179 | vector get_required_rasters(LSDFlowInfo& FlowInfo); 180 | 181 | 182 | /// @brief This calculates the suspended and bedload for a given node in the DEM 183 | /// It can be called repeatedly to get the entire DEM 184 | /// @param node The node at which you want to calculate suspended and bedload 185 | /// @param FlowInfo the LSDFlowinfo object 186 | /// @param RasterVec a vector of LSDRasters, the first element is the DEM, 187 | /// the second element is the lithology, the third element is the flow distance 188 | /// and the fourth element is the erosion rate 189 | /// @return a vector containg the bedload and suspended load information 190 | /// @author SMM 191 | /// @date 22/03/2016 192 | vector calculate_suspended_and_bedload(int node, LSDFlowInfo& FlowInfo, 193 | vector RasterVec); 194 | 195 | 196 | protected: 197 | 198 | /// The number of lithologies 199 | int N_lithologies; 200 | 201 | /// the erosion rate in mm/yr 202 | float erosion_rate; 203 | 204 | /// The erodibiliy coefficients in km^-1 205 | /// The int is the index into the lithology (coded with an integer) 206 | map erodibility_coefficients; 207 | 208 | /// The fertility coefficients: states the fraction in the source material 209 | /// that contains zircon 210 | /// The int is the index into the lithology (coded with an integer) 211 | map fertility_coefficients; 212 | 213 | /// The fraction of the source material that is entered as suspended load 214 | /// The int is the index into the lithology (coded with an integer) 215 | map source_1mm; 216 | 217 | 218 | private: 219 | 220 | /// @brief the create function used when calling a file 221 | /// @param the path to the file. Must have the "/" at the end 222 | /// @param file_prefix the prefix (without extension) of the parameter files 223 | /// @author SMM 224 | /// @date 10/02/2016 225 | void create(string path, string file_prefix); 226 | 227 | }; 228 | 229 | 230 | 231 | #endif -------------------------------------------------------------------------------- /src/LSDRasterInfo.hpp: -------------------------------------------------------------------------------- 1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2 | // 3 | // LSDRaster 4 | // Land Surface Dynamics Raster Info 5 | // 6 | // An object within the University 7 | // of Edinburgh Land Surface Dynamics group topographic toolbox 8 | // for examining the georeferencing and existence of rasters 9 | // 10 | // Developed by: 11 | // Simon M. Mudd 12 | // Martin D. Hurst 13 | // David T. Milodowski 14 | // Stuart W.D. Grieve 15 | // Declan A. Valters 16 | // Fiona Clubb 17 | // 18 | // Copyright (C) 2013 Simon M. Mudd 2013 19 | // 20 | // Developer can be contacted by simon.m.mudd _at_ ed.ac.uk 21 | // 22 | // Simon Mudd 23 | // University of Edinburgh 24 | // School of GeoSciences 25 | // Drummond Street 26 | // Edinburgh, EH8 9XP 27 | // Scotland 28 | // United Kingdom 29 | // 30 | // This program is free software; 31 | // you can redistribute it and/or modify it under the terms of the 32 | // GNU General Public License as published by the Free Software Foundation; 33 | // either version 2 of the License, or (at your option) any later version. 34 | // 35 | // This program is distributed in the hope that it will be useful, 36 | // but WITHOUT ANY WARRANTY; 37 | // without even the implied warranty of 38 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 39 | // See the GNU General Public License for more details. 40 | // 41 | // You should have received a copy of the 42 | // GNU General Public License along with this program; 43 | // if not, write to: 44 | // Free Software Foundation, Inc., 45 | // 51 Franklin Street, Fifth Floor, 46 | // Boston, MA 02110-1301 47 | // USA 48 | // 49 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 50 | 51 | 52 | #ifndef LSDRasterInfo_H 53 | #define LSDRasterInfo_H 54 | 55 | #include 56 | #include 57 | using namespace std; 58 | 59 | // declare classes. Implementation is included in cpp file 60 | class LSDRaster; 61 | class LSDTindexRaster; 62 | 63 | ///@brief Object that stores georeferencing information. This information is 64 | /// also stored with the raster, it is seperated here mainly to compare 65 | /// different datasets 66 | class LSDRasterInfo 67 | { 68 | public: 69 | 70 | /// an empty create function 71 | LSDRasterInfo() { create(); } 72 | 73 | /// This function reads the file 74 | LSDRasterInfo(string filename, string extension) 75 | { create(filename, extension); } 76 | 77 | /// This gets the information from an existing raster 78 | LSDRasterInfo(LSDRaster& Raster) 79 | { create(Raster); } 80 | 81 | /// This gets the information from an existing index raster 82 | LSDRasterInfo(LSDIndexRaster& IRaster) 83 | { create(IRaster); } 84 | 85 | /// The equality operator 86 | bool operator==(LSDRasterInfo& LSDRI); 87 | 88 | /// The inequality operator 89 | bool operator!=(LSDRasterInfo& LSDRI); 90 | 91 | /// @brief this function gets the UTM_zone and a boolean that is true if 92 | /// the map is in the northern hemisphere 93 | /// @param UTM_zone the UTM zone. Replaced in function. 94 | /// @param is_North a boolean that is true if the DEM is in the northern hemisphere. 95 | /// replaced in function 96 | /// @author SMM 97 | /// @date 22/12/2014 98 | void get_UTM_information(int& UTM_zone, bool& is_North); 99 | 100 | /// @brief this check to see if a point is within the raster 101 | /// @param X_coordinate the x location of the point 102 | /// @param Y_coordinate the y location of the point 103 | /// @return is_in_raster a boolean telling if the point is in the raster 104 | /// @author SMM 105 | /// @date 13/11/2014 106 | bool check_if_point_is_in_raster(float X_coordinate,float Y_coordinate); 107 | 108 | /// @brief Prints the raster information to screen 109 | /// @author SMM 110 | /// @date 19/11/2019 111 | void print_raster_information(); 112 | 113 | // Get functions 114 | /// @return Number of rows as an integer. 115 | int get_NRows() const { return NRows; } 116 | /// @return Number of columns as an integer. 117 | int get_NCols() const { return NCols; } 118 | /// @return Minimum X coordinate as an integer. 119 | float get_XMinimum() const { return XMinimum; } 120 | /// @return Minimum Y coordinate as an integer. 121 | float get_YMinimum() const { return YMinimum; } 122 | /// @return Data resolution as an integer. 123 | float get_DataResolution() const { return DataResolution; } 124 | /// @return No Data Value as an integer. 125 | int get_NoDataValue() const { return NoDataValue; } 126 | /// @return map containing the georeferencing strings 127 | map get_GeoReferencingStrings() const { return GeoReferencingStrings; } 128 | 129 | protected: 130 | 131 | /// @brief Read a header 132 | /// The supported formats are .asc, .flt and .bil which are 133 | /// both exported and imported by arcmap. 134 | /// The filename is the string of characters before the '.' in the extension 135 | /// and the extension is the characters after the '.'. 136 | /// If the full filename is my_dem.01.asc then: 137 | /// filename = "my_dem.01" and extension = "asc". 138 | /// For float files both a data file and a header are read 139 | /// the header file must have the same filename, before extention, of 140 | /// the raster data, and the extension must be .hdr. 141 | /// @param filename the prefix of the file 142 | /// @param extension this is either "asc", "flt", or "bil" 143 | /// @author SMM 144 | /// @date 01/01/12 145 | void read_header(string filename, string extension); 146 | 147 | 148 | 149 | ///Number of rows. 150 | int NRows; 151 | ///Number of columns. 152 | int NCols; 153 | ///Minimum X coordinate. 154 | float XMinimum; 155 | ///Minimum Y coordinate. 156 | float YMinimum; 157 | ///Data resolution. 158 | float DataResolution; 159 | ///No data value. 160 | int NoDataValue; 161 | 162 | ///A map of strings for holding georeferencing information 163 | map GeoReferencingStrings; 164 | 165 | 166 | private: 167 | void create(); 168 | void create(LSDRaster& Raster); 169 | void create(LSDIndexRaster& IRaster); 170 | void create(string filename, string extension); 171 | 172 | }; 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /src/TNT/jama_cholesky.h: -------------------------------------------------------------------------------- 1 | #ifndef JAMA_CHOLESKY_H 2 | #define JAMA_CHOLESKY_H 3 | 4 | #include "math.h" 5 | /* needed for sqrt() below. */ 6 | 7 | 8 | namespace JAMA 9 | { 10 | 11 | using namespace TNT; 12 | 13 | /** 14 |

15 | For a symmetric, positive definite matrix A, this function 16 | computes the Cholesky factorization, i.e. it computes a lower 17 | triangular matrix L such that A = L*L'. 18 | If the matrix is not symmetric or positive definite, the function 19 | computes only a partial decomposition. This can be tested with 20 | the is_spd() flag. 21 | 22 |

Typical usage looks like: 23 |

 24 | 	Array2D A(n,n);
 25 | 	Array2D L;
 26 | 
 27 | 	 ... 
 28 | 
 29 | 	Cholesky chol(A);
 30 | 
 31 | 	if (chol.is_spd())
 32 | 		L = chol.getL();
 33 | 		
 34 |   	else
 35 | 		cout << "factorization was not complete.\n";
 36 | 
 37 | 	
38 | 39 | 40 |

41 | (Adapted from JAMA, a Java Matrix Library, developed by jointly 42 | by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama). 43 | 44 | */ 45 | 46 | template 47 | class Cholesky 48 | { 49 | Array2D L_; // lower triangular factor 50 | int isspd; // 1 if matrix to be factored was SPD 51 | 52 | public: 53 | 54 | Cholesky(); 55 | Cholesky(const Array2D &A); 56 | Array2D getL() const; 57 | Array1D solve(const Array1D &B); 58 | Array2D solve(const Array2D &B); 59 | int is_spd() const; 60 | 61 | }; 62 | 63 | template 64 | Cholesky::Cholesky() : L_(0,0), isspd(0) {} 65 | 66 | /** 67 | @return 1, if original matrix to be factored was symmetric 68 | positive-definite (SPD). 69 | */ 70 | template 71 | int Cholesky::is_spd() const 72 | { 73 | return isspd; 74 | } 75 | 76 | /** 77 | @return the lower triangular factor, L, such that L*L'=A. 78 | */ 79 | template 80 | Array2D Cholesky::getL() const 81 | { 82 | return L_; 83 | } 84 | 85 | /** 86 | Constructs a lower triangular matrix L, such that L*L'= A. 87 | If A is not symmetric positive-definite (SPD), only a 88 | partial factorization is performed. If is_spd() 89 | evalutate true (1) then the factorizaiton was successful. 90 | */ 91 | template 92 | Cholesky::Cholesky(const Array2D &A) 93 | { 94 | 95 | 96 | int m = A.dim1(); 97 | int n = A.dim2(); 98 | 99 | isspd = (m == n); 100 | 101 | if (m != n) 102 | { 103 | L_ = Array2D(0,0); 104 | return; 105 | } 106 | 107 | L_ = Array2D(n,n); 108 | 109 | 110 | // Main loop. 111 | for (int j = 0; j < n; j++) 112 | { 113 | Real d(0.0); 114 | for (int k = 0; k < j; k++) 115 | { 116 | Real s(0.0); 117 | for (int i = 0; i < k; i++) 118 | { 119 | s += L_[k][i]*L_[j][i]; 120 | } 121 | L_[j][k] = s = (A[j][k] - s)/L_[k][k]; 122 | d = d + s*s; 123 | isspd = isspd && (A[k][j] == A[j][k]); 124 | } 125 | d = A[j][j] - d; 126 | isspd = isspd && (d > 0.0); 127 | L_[j][j] = sqrt(d > 0.0 ? d : 0.0); 128 | for (int k = j+1; k < n; k++) 129 | { 130 | L_[j][k] = 0.0; 131 | } 132 | } 133 | } 134 | 135 | /** 136 | 137 | Solve a linear system A*x = b, using the previously computed 138 | cholesky factorization of A: L*L'. 139 | 140 | @param B A Matrix with as many rows as A and any number of columns. 141 | @return x so that L*L'*x = b. If b is nonconformat, or if A 142 | was not symmetric posidtive definite, a null (0x0) 143 | array is returned. 144 | */ 145 | template 146 | Array1D Cholesky::solve(const Array1D &b) 147 | { 148 | int n = L_.dim1(); 149 | if (b.dim1() != n) 150 | return Array1D(); 151 | 152 | 153 | Array1D x = b.copy(); 154 | 155 | 156 | // Solve L*y = b; 157 | for (int k = 0; k < n; k++) 158 | { 159 | for (int i = 0; i < k; i++) 160 | x[k] -= x[i]*L_[k][i]; 161 | x[k] /= L_[k][k]; 162 | 163 | } 164 | 165 | // Solve L'*X = Y; 166 | for (int k = n-1; k >= 0; k--) 167 | { 168 | for (int i = k+1; i < n; i++) 169 | x[k] -= x[i]*L_[i][k]; 170 | x[k] /= L_[k][k]; 171 | } 172 | 173 | return x; 174 | } 175 | 176 | 177 | /** 178 | 179 | Solve a linear system A*X = B, using the previously computed 180 | cholesky factorization of A: L*L'. 181 | 182 | @param B A Matrix with as many rows as A and any number of columns. 183 | @return X so that L*L'*X = B. If B is nonconformat, or if A 184 | was not symmetric posidtive definite, a null (0x0) 185 | array is returned. 186 | */ 187 | template 188 | Array2D Cholesky::solve(const Array2D &B) 189 | { 190 | int n = L_.dim1(); 191 | if (B.dim1() != n) 192 | return Array2D(); 193 | 194 | 195 | Array2D X = B.copy(); 196 | int nx = B.dim2(); 197 | 198 | // Cleve's original code 199 | #if 0 200 | // Solve L*Y = B; 201 | for (int k = 0; k < n; k++) { 202 | for (int i = k+1; i < n; i++) { 203 | for (int j = 0; j < nx; j++) { 204 | X[i][j] -= X[k][j]*L_[k][i]; 205 | } 206 | } 207 | for (int j = 0; j < nx; j++) { 208 | X[k][j] /= L_[k][k]; 209 | } 210 | } 211 | 212 | // Solve L'*X = Y; 213 | for (int k = n-1; k >= 0; k--) { 214 | for (int j = 0; j < nx; j++) { 215 | X[k][j] /= L_[k][k]; 216 | } 217 | for (int i = 0; i < k; i++) { 218 | for (int j = 0; j < nx; j++) { 219 | X[i][j] -= X[k][j]*L_[k][i]; 220 | } 221 | } 222 | } 223 | #endif 224 | 225 | 226 | // Solve L*y = b; 227 | for (int j=0; j< nx; j++) 228 | { 229 | for (int k = 0; k < n; k++) 230 | { 231 | for (int i = 0; i < k; i++) 232 | X[k][j] -= X[i][j]*L_[k][i]; 233 | X[k][j] /= L_[k][k]; 234 | } 235 | } 236 | 237 | // Solve L'*X = Y; 238 | for (int j=0; j= 0; k--) 241 | { 242 | for (int i = k+1; i < n; i++) 243 | X[k][j] -= X[i][j]*L_[i][k]; 244 | X[k][j] /= L_[k][k]; 245 | } 246 | } 247 | 248 | 249 | 250 | return X; 251 | } 252 | 253 | 254 | } 255 | // namespace JAMA 256 | 257 | #endif 258 | // JAMA_CHOLESKY_H 259 | -------------------------------------------------------------------------------- /src/TNT/jama_lu.h: -------------------------------------------------------------------------------- 1 | #ifndef JAMA_LU_H 2 | #define JAMA_LU_H 3 | 4 | #include "tnt.h" 5 | #include 6 | //for min(), max() below 7 | 8 | using namespace TNT; 9 | using namespace std; 10 | 11 | namespace JAMA 12 | { 13 | 14 | /** LU Decomposition. 15 |

16 | For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n 17 | unit lower triangular matrix L, an n-by-n upper triangular matrix U, 18 | and a permutation vector piv of length m so that A(piv,:) = L*U. 19 | If m < n, then L is m-by-m and U is m-by-n. 20 |

21 | The LU decompostion with pivoting always exists, even if the matrix is 22 | singular, so the constructor will never fail. The primary use of the 23 | LU decomposition is in the solution of square systems of simultaneous 24 | linear equations. This will fail if isNonsingular() returns false. 25 | */ 26 | template 27 | class LU 28 | { 29 | 30 | 31 | 32 | /* Array for internal storage of decomposition. */ 33 | Array2D LU_; 34 | int m, n, pivsign; 35 | Array1D piv; 36 | 37 | 38 | Array2D permute_copy(const Array2D &A, 39 | const Array1D &piv, int j0, int j1) 40 | { 41 | int piv_length = piv.dim(); 42 | 43 | Array2D X(piv_length, j1-j0+1); 44 | 45 | 46 | for (int i = 0; i < piv_length; i++) 47 | for (int j = j0; j <= j1; j++) 48 | X[i][j-j0] = A[piv[i]][j]; 49 | 50 | return X; 51 | } 52 | 53 | Array1D permute_copy(const Array1D &A, 54 | const Array1D &piv) 55 | { 56 | int piv_length = piv.dim(); 57 | if (piv_length != A.dim()) 58 | return Array1D(); 59 | 60 | Array1D x(piv_length); 61 | 62 | 63 | for (int i = 0; i < piv_length; i++) 64 | x[i] = A[piv[i]]; 65 | 66 | return x; 67 | } 68 | 69 | 70 | public : 71 | 72 | /** LU Decomposition 73 | @param A Rectangular matrix 74 | @return LU Decomposition object to access L, U and piv. 75 | */ 76 | 77 | LU (const Array2D &A) : LU_(A.copy()), m(A.dim1()), n(A.dim2()), 78 | piv(A.dim1()) 79 | 80 | { 81 | 82 | // Use a "left-looking", dot-product, Crout/Doolittle algorithm. 83 | 84 | 85 | for (int i = 0; i < m; i++) { 86 | piv[i] = i; 87 | } 88 | pivsign = 1; 89 | Real *LUrowi = 0;; 90 | Array1D LUcolj(m); 91 | 92 | // Outer loop. 93 | 94 | for (int j = 0; j < n; j++) { 95 | 96 | // Make a copy of the j-th column to localize references. 97 | 98 | for (int i = 0; i < m; i++) { 99 | LUcolj[i] = LU_[i][j]; 100 | } 101 | 102 | // Apply previous transformations. 103 | 104 | for (int i = 0; i < m; i++) { 105 | LUrowi = LU_[i]; 106 | 107 | // Most of the time is spent in the following dot product. 108 | 109 | int kmax = min(i,j); 110 | double s = 0.0; 111 | for (int k = 0; k < kmax; k++) { 112 | s += LUrowi[k]*LUcolj[k]; 113 | } 114 | 115 | LUrowi[j] = LUcolj[i] -= s; 116 | } 117 | 118 | // Find pivot and exchange if necessary. 119 | 120 | int p = j; 121 | for (int i = j+1; i < m; i++) { 122 | if (abs(LUcolj[i]) > abs(LUcolj[p])) { 123 | p = i; 124 | } 125 | } 126 | if (p != j) { 127 | int k=0; 128 | for (k = 0; k < n; k++) { 129 | double t = LU_[p][k]; 130 | LU_[p][k] = LU_[j][k]; 131 | LU_[j][k] = t; 132 | } 133 | k = piv[p]; 134 | piv[p] = piv[j]; 135 | piv[j] = k; 136 | pivsign = -pivsign; 137 | } 138 | 139 | // Compute multipliers. 140 | 141 | if ((j < m) && (LU_[j][j] != 0.0)) { 142 | for (int i = j+1; i < m; i++) { 143 | LU_[i][j] /= LU_[j][j]; 144 | } 145 | } 146 | } 147 | } 148 | 149 | 150 | /** Is the matrix nonsingular? 151 | @return 1 (true) if upper triangular factor U (and hence A) 152 | is nonsingular, 0 otherwise. 153 | */ 154 | 155 | int isNonsingular () { 156 | for (int j = 0; j < n; j++) { 157 | if (LU_[j][j] == 0) 158 | return 0; 159 | } 160 | return 1; 161 | } 162 | 163 | /** Return lower triangular factor 164 | @return L 165 | */ 166 | 167 | Array2D getL () { 168 | Array2D L_(m,n); 169 | for (int i = 0; i < m; i++) { 170 | for (int j = 0; j < n; j++) { 171 | if (i > j) { 172 | L_[i][j] = LU_[i][j]; 173 | } else if (i == j) { 174 | L_[i][j] = 1.0; 175 | } else { 176 | L_[i][j] = 0.0; 177 | } 178 | } 179 | } 180 | return L_; 181 | } 182 | 183 | /** Return upper triangular factor 184 | @return U portion of LU factorization. 185 | */ 186 | 187 | Array2D getU () { 188 | Array2D U_(n,n); 189 | for (int i = 0; i < n; i++) { 190 | for (int j = 0; j < n; j++) { 191 | if (i <= j) { 192 | U_[i][j] = LU_[i][j]; 193 | } else { 194 | U_[i][j] = 0.0; 195 | } 196 | } 197 | } 198 | return U_; 199 | } 200 | 201 | /** Return pivot permutation vector 202 | @return piv 203 | */ 204 | 205 | Array1D getPivot () { 206 | return piv; 207 | } 208 | 209 | 210 | /** Compute determinant using LU factors. 211 | @return determinant of A, or 0 if A is not square. 212 | */ 213 | 214 | Real det () { 215 | if (m != n) { 216 | return Real(0); 217 | } 218 | Real d = Real(pivsign); 219 | for (int j = 0; j < n; j++) { 220 | d *= LU_[j][j]; 221 | } 222 | return d; 223 | } 224 | 225 | /** Solve A*X = B 226 | @param B A Matrix with as many rows as A and any number of columns. 227 | @return X so that L*U*X = B(piv,:), if B is nonconformant, returns 228 | 0x0 (null) array. 229 | */ 230 | 231 | Array2D solve (const Array2D &B) 232 | { 233 | 234 | /* Dimensions: A is mxn, X is nxk, B is mxk */ 235 | 236 | if (B.dim1() != m) { 237 | return Array2D(0,0); 238 | } 239 | if (!isNonsingular()) { 240 | return Array2D(0,0); 241 | } 242 | 243 | // Copy right hand side with pivoting 244 | int nx = B.dim2(); 245 | 246 | 247 | Array2D X = permute_copy(B, piv, 0, nx-1); 248 | 249 | // Solve L*Y = B(piv,:) 250 | for (int k = 0; k < n; k++) { 251 | for (int i = k+1; i < n; i++) { 252 | for (int j = 0; j < nx; j++) { 253 | X[i][j] -= X[k][j]*LU_[i][k]; 254 | } 255 | } 256 | } 257 | // Solve U*X = Y; 258 | for (int k = n-1; k >= 0; k--) { 259 | for (int j = 0; j < nx; j++) { 260 | X[k][j] /= LU_[k][k]; 261 | } 262 | for (int i = 0; i < k; i++) { 263 | for (int j = 0; j < nx; j++) { 264 | X[i][j] -= X[k][j]*LU_[i][k]; 265 | } 266 | } 267 | } 268 | return X; 269 | } 270 | 271 | 272 | /** Solve A*x = b, where x and b are vectors of length equal 273 | to the number of rows in A. 274 | 275 | @param b a vector (Array1D> of length equal to the first dimension 276 | of A. 277 | @return x a vector (Array1D> so that L*U*x = b(piv), if B is nonconformant, 278 | returns 0x0 (null) array. 279 | */ 280 | 281 | Array1D solve (const Array1D &b) 282 | { 283 | 284 | /* Dimensions: A is mxn, X is nxk, B is mxk */ 285 | 286 | if (b.dim1() != m) { 287 | return Array1D(); 288 | } 289 | if (!isNonsingular()) { 290 | return Array1D(); 291 | } 292 | 293 | 294 | Array1D x = permute_copy(b, piv); 295 | 296 | // Solve L*Y = B(piv) 297 | for (int k = 0; k < n; k++) { 298 | for (int i = k+1; i < n; i++) { 299 | x[i] -= x[k]*LU_[i][k]; 300 | } 301 | } 302 | 303 | // Solve U*X = Y; 304 | for (int k = n-1; k >= 0; k--) { 305 | x[k] /= LU_[k][k]; 306 | for (int i = 0; i < k; i++) 307 | x[i] -= x[k]*LU_[i][k]; 308 | } 309 | 310 | 311 | return x; 312 | } 313 | 314 | }; /* class LU */ 315 | 316 | } /* namespace JAMA */ 317 | 318 | #endif 319 | /* JAMA_LU_H */ 320 | -------------------------------------------------------------------------------- /src/TNT/jama_qr.h: -------------------------------------------------------------------------------- 1 | #ifndef JAMA_QR_H 2 | #define JAMA_QR_H 3 | 4 | #include "tnt_array1d.h" 5 | #include "tnt_array2d.h" 6 | #include "tnt_math_utils.h" 7 | 8 | namespace JAMA 9 | { 10 | 11 | /** 12 |

13 | Classical QR Decompisition: 14 | for an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n 15 | orthogonal matrix Q and an n-by-n upper triangular matrix R so that 16 | A = Q*R. 17 |

18 | The QR decompostion always exists, even if the matrix does not have 19 | full rank, so the constructor will never fail. The primary use of the 20 | QR decomposition is in the least squares solution of nonsquare systems 21 | of simultaneous linear equations. This will fail if isFullRank() 22 | returns 0 (false). 23 | 24 |

25 | The Q and R factors can be retrived via the getQ() and getR() 26 | methods. Furthermore, a solve() method is provided to find the 27 | least squares solution of Ax=b using the QR factors. 28 | 29 |

30 | (Adapted from JAMA, a Java Matrix Library, developed by jointly 31 | by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama). 32 | */ 33 | 34 | template 35 | class QR { 36 | 37 | 38 | /** Array for internal storage of decomposition. 39 | @serial internal array storage. 40 | */ 41 | 42 | TNT::Array2D QR_; 43 | 44 | /** Row and column dimensions. 45 | @serial column dimension. 46 | @serial row dimension. 47 | */ 48 | int m, n; 49 | 50 | /** Array for internal storage of diagonal of R. 51 | @serial diagonal of R. 52 | */ 53 | TNT::Array1D Rdiag; 54 | 55 | 56 | public: 57 | 58 | /** 59 | Create a QR factorization object for A. 60 | 61 | @param A rectangular (m>=n) matrix. 62 | */ 63 | QR(const TNT::Array2D &A) /* constructor */ 64 | { 65 | QR_ = A.copy(); 66 | m = A.dim1(); 67 | n = A.dim2(); 68 | Rdiag = TNT::Array1D(n); 69 | int i=0, j=0, k=0; 70 | 71 | // Main loop. 72 | for (k = 0; k < n; k++) { 73 | // Compute 2-norm of k-th column without under/overflow. 74 | Real nrm = 0; 75 | for (i = k; i < m; i++) { 76 | nrm = TNT::hypot(nrm,QR_[i][k]); 77 | } 78 | 79 | if (nrm != 0.0) { 80 | // Form k-th Householder vector. 81 | if (QR_[k][k] < 0) { 82 | nrm = -nrm; 83 | } 84 | for (i = k; i < m; i++) { 85 | QR_[i][k] /= nrm; 86 | } 87 | QR_[k][k] += 1.0; 88 | 89 | // Apply transformation to remaining columns. 90 | for (j = k+1; j < n; j++) { 91 | Real s = 0.0; 92 | for (i = k; i < m; i++) { 93 | s += QR_[i][k]*QR_[i][j]; 94 | } 95 | s = -s/QR_[k][k]; 96 | for (i = k; i < m; i++) { 97 | QR_[i][j] += s*QR_[i][k]; 98 | } 99 | } 100 | } 101 | Rdiag[k] = -nrm; 102 | } 103 | } 104 | 105 | 106 | /** 107 | Flag to denote the matrix is of full rank. 108 | 109 | @return 1 if matrix is full rank, 0 otherwise. 110 | */ 111 | int isFullRank() const 112 | { 113 | for (int j = 0; j < n; j++) 114 | { 115 | if (Rdiag[j] == 0) 116 | return 0; 117 | } 118 | return 1; 119 | } 120 | 121 | 122 | 123 | 124 | /** 125 | 126 | Retreive the Householder vectors from QR factorization 127 | @returns lower trapezoidal matrix whose columns define the reflections 128 | */ 129 | 130 | TNT::Array2D getHouseholder (void) const 131 | { 132 | TNT::Array2D H(m,n); 133 | 134 | /* note: H is completely filled in by algorithm, so 135 | initializaiton of H is not necessary. 136 | */ 137 | for (int i = 0; i < m; i++) 138 | { 139 | for (int j = 0; j < n; j++) 140 | { 141 | if (i >= j) { 142 | H[i][j] = QR_[i][j]; 143 | } else { 144 | H[i][j] = 0.0; 145 | } 146 | } 147 | } 148 | return H; 149 | } 150 | 151 | 152 | 153 | /** Return the upper triangular factor, R, of the QR factorization 154 | @return R 155 | */ 156 | 157 | TNT::Array2D getR() const 158 | { 159 | TNT::Array2D R(n,n); 160 | for (int i = 0; i < n; i++) { 161 | for (int j = 0; j < n; j++) { 162 | if (i < j) { 163 | R[i][j] = QR_[i][j]; 164 | } else if (i == j) { 165 | R[i][j] = Rdiag[i]; 166 | } else { 167 | R[i][j] = 0.0; 168 | } 169 | } 170 | } 171 | return R; 172 | } 173 | 174 | 175 | 176 | 177 | 178 | /** 179 | Generate and return the (economy-sized) orthogonal factor 180 | @param Q the (ecnomy-sized) orthogonal factor (Q*R=A). 181 | */ 182 | 183 | TNT::Array2D getQ() const 184 | { 185 | int i=0, j=0, k=0; 186 | 187 | TNT::Array2D Q(m,n); 188 | for (k = n-1; k >= 0; k--) { 189 | for (i = 0; i < m; i++) { 190 | Q[i][k] = 0.0; 191 | } 192 | Q[k][k] = 1.0; 193 | for (j = k; j < n; j++) { 194 | if (QR_[k][k] != 0) { 195 | Real s = 0.0; 196 | for (i = k; i < m; i++) { 197 | s += QR_[i][k]*Q[i][j]; 198 | } 199 | s = -s/QR_[k][k]; 200 | for (i = k; i < m; i++) { 201 | Q[i][j] += s*QR_[i][k]; 202 | } 203 | } 204 | } 205 | } 206 | return Q; 207 | } 208 | 209 | 210 | /** Least squares solution of A*x = b 211 | @param B m-length array (vector). 212 | @return x n-length array (vector) that minimizes the two norm of Q*R*X-B. 213 | If B is non-conformant, or if QR.isFullRank() is false, 214 | the routine returns a null (0-length) vector. 215 | */ 216 | 217 | TNT::Array1D solve(const TNT::Array1D &b) const 218 | { 219 | if (b.dim1() != m) /* arrays must be conformant */ 220 | return TNT::Array1D(); 221 | 222 | if ( !isFullRank() ) /* matrix is rank deficient */ 223 | { 224 | return TNT::Array1D(); 225 | } 226 | 227 | TNT::Array1D x = b.copy(); 228 | 229 | // Compute Y = transpose(Q)*b 230 | for (int k = 0; k < n; k++) 231 | { 232 | Real s = 0.0; 233 | for (int i = k; i < m; i++) 234 | { 235 | s += QR_[i][k]*x[i]; 236 | } 237 | s = -s/QR_[k][k]; 238 | for (int i = k; i < m; i++) 239 | { 240 | x[i] += s*QR_[i][k]; 241 | } 242 | } 243 | // Solve R*X = Y; 244 | for (int k = n-1; k >= 0; k--) 245 | { 246 | x[k] /= Rdiag[k]; 247 | for (int i = 0; i < k; i++) { 248 | x[i] -= x[k]*QR_[i][k]; 249 | } 250 | } 251 | 252 | 253 | /* return n x nx portion of X */ 254 | TNT::Array1D x_(n); 255 | for (int i=0; i solve(const TNT::Array2D &B) const 269 | { 270 | if (B.dim1() != m) /* arrays must be conformant */ 271 | return TNT::Array2D(0,0); 272 | 273 | if ( !isFullRank() ) /* matrix is rank deficient */ 274 | { 275 | return TNT::Array2D(0,0); 276 | } 277 | 278 | int nx = B.dim2(); 279 | TNT::Array2D X = B.copy(); 280 | int i=0, j=0, k=0; 281 | 282 | // Compute Y = transpose(Q)*B 283 | for (k = 0; k < n; k++) { 284 | for (j = 0; j < nx; j++) { 285 | Real s = 0.0; 286 | for (i = k; i < m; i++) { 287 | s += QR_[i][k]*X[i][j]; 288 | } 289 | s = -s/QR_[k][k]; 290 | for (i = k; i < m; i++) { 291 | X[i][j] += s*QR_[i][k]; 292 | } 293 | } 294 | } 295 | // Solve R*X = Y; 296 | for (k = n-1; k >= 0; k--) { 297 | for (j = 0; j < nx; j++) { 298 | X[k][j] /= Rdiag[k]; 299 | } 300 | for (i = 0; i < k; i++) { 301 | for (j = 0; j < nx; j++) { 302 | X[i][j] -= X[k][j]*QR_[i][k]; 303 | } 304 | } 305 | } 306 | 307 | 308 | /* return n x nx portion of X */ 309 | TNT::Array2D X_(n,nx); 310 | for (i=0; i 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | 33 | #include "tnt_i_refvec.h" 34 | 35 | namespace TNT 36 | { 37 | 38 | template 39 | class Array1D 40 | { 41 | 42 | private: 43 | 44 | /* ... */ 45 | i_refvec v_; 46 | int n_; 47 | T* data_; /* this normally points to v_.begin(), but 48 | * could also point to a portion (subvector) 49 | * of v_. 50 | */ 51 | 52 | void copy_(T* p, const T* q, int len) const; 53 | void set_(T* begin, T* end, const T& val); 54 | 55 | 56 | public: 57 | 58 | typedef T value_type; 59 | 60 | 61 | Array1D(); 62 | explicit Array1D(int n); 63 | Array1D(int n, const T &a); 64 | Array1D(int n, T *a); 65 | Array1D(int n, const T *a); 66 | inline Array1D(const Array1D &A); 67 | inline operator T*(); 68 | inline operator const T*(); 69 | inline Array1D & operator=(const T &a); 70 | inline Array1D & operator=(const Array1D &A); 71 | inline Array1D & ref(const Array1D &A); 72 | Array1D copy() const; 73 | Array1D & inject(const Array1D & A); 74 | inline T& operator[](int i); 75 | inline const T& operator[](int i) const; 76 | inline int dim1() const; 77 | inline int dim() const; 78 | ~Array1D(); 79 | 80 | 81 | /* ... extended interface ... */ 82 | 83 | inline int ref_count() const; 84 | inline Array1D subarray(int i0, int i1); 85 | 86 | }; 87 | 88 | 89 | 90 | 91 | template 92 | Array1D::Array1D() : v_(), n_(0), data_(0) {} 93 | 94 | template 95 | Array1D::Array1D(const Array1D &A) : v_(A.v_), n_(A.n_), 96 | data_(A.data_) 97 | { 98 | #ifdef TNT_DEBUG 99 | std::cout << "Created Array1D(const Array1D &A) \n"; 100 | #endif 101 | 102 | } 103 | 104 | 105 | template 106 | Array1D::Array1D(int n) : v_(n), n_(n), data_(v_.begin()) 107 | { 108 | #ifdef TNT_DEBUG 109 | std::cout << "Created Array1D(int n) \n"; 110 | #endif 111 | } 112 | 113 | template 114 | Array1D::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin()) 115 | { 116 | #ifdef TNT_DEBUG 117 | std::cout << "Created Array1D(int n, const T& val) \n"; 118 | #endif 119 | set_(data_, data_+ n, val); 120 | 121 | } 122 | 123 | template 124 | Array1D::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin()) 125 | { 126 | #ifdef TNT_DEBUG 127 | std::cout << "Created Array1D(int n, T* a) \n"; 128 | #endif 129 | } 130 | 131 | template 132 | Array1D::Array1D(int n, const T *a) : v_(a), n_(n), data_(v_.begin()) 133 | { 134 | #ifndef TNT_DEBUG 135 | std::cout << "Created Array1D(int n, const T* a) \n"; 136 | #endif 137 | } 138 | 139 | template 140 | inline Array1D::operator T*() 141 | { 142 | return &(v_[0]); 143 | } 144 | 145 | 146 | template 147 | inline Array1D::operator const T*() 148 | { 149 | return &(v_[0]); 150 | } 151 | 152 | 153 | 154 | template 155 | inline T& Array1D::operator[](int i) 156 | { 157 | #ifdef TNT_BOUNDS_CHECK 158 | assert(i>= 0); 159 | assert(i < n_); 160 | #endif 161 | return data_[i]; 162 | } 163 | 164 | template 165 | inline const T& Array1D::operator[](int i) const 166 | { 167 | #ifdef TNT_BOUNDS_CHECK 168 | assert(i>= 0); 169 | assert(i < n_); 170 | #endif 171 | return data_[i]; 172 | } 173 | 174 | 175 | 176 | 177 | template 178 | Array1D & Array1D::operator=(const T &a) 179 | { 180 | set_(data_, data_+n_, a); 181 | return *this; 182 | } 183 | 184 | template 185 | Array1D Array1D::copy() const 186 | { 187 | Array1D A( n_); 188 | copy_(A.data_, data_, n_); 189 | 190 | return A; 191 | } 192 | 193 | 194 | template 195 | Array1D & Array1D::inject(const Array1D &A) 196 | { 197 | if (A.n_ == n_) 198 | copy_(data_, A.data_, n_); 199 | 200 | return *this; 201 | } 202 | 203 | 204 | 205 | 206 | 207 | template 208 | Array1D & Array1D::ref(const Array1D &A) 209 | { 210 | if (this != &A) 211 | { 212 | v_ = A.v_; /* operator= handles the reference counting. */ 213 | n_ = A.n_; 214 | data_ = A.data_; 215 | 216 | } 217 | return *this; 218 | } 219 | 220 | template 221 | Array1D & Array1D::operator=(const Array1D &A) 222 | { 223 | return ref(A); 224 | } 225 | 226 | template 227 | inline int Array1D::dim1() const { return n_; } 228 | 229 | template 230 | inline int Array1D::dim() const { return n_; } 231 | 232 | template 233 | Array1D::~Array1D() {} 234 | 235 | 236 | /* ............................ exented interface ......................*/ 237 | 238 | template 239 | inline int Array1D::ref_count() const 240 | { 241 | return v_.ref_count(); 242 | } 243 | 244 | template 245 | inline Array1D Array1D::subarray(int i0, int i1) 246 | { 247 | if ((i0 > 0) && (i1 < n_) || (i0 <= i1)) 248 | { 249 | Array1D X(*this); /* create a new instance of this array. */ 250 | X.n_ = i1-i0+1; 251 | X.data_ += i0; 252 | 253 | return X; 254 | } 255 | else 256 | { 257 | return Array1D(); 258 | } 259 | } 260 | 261 | 262 | /* private internal functions */ 263 | 264 | 265 | template 266 | void Array1D::set_(T* begin, T* end, const T& a) 267 | { 268 | for (T* p=begin; p 274 | void Array1D::copy_(T* p, const T* q, int len) const 275 | { 276 | T *end = p + len; 277 | while (p 24 | #include 25 | 26 | namespace TNT 27 | { 28 | 29 | 30 | template 31 | std::ostream& operator<<(std::ostream &s, const Array1D &A) 32 | { 33 | int N=A.dim1(); 34 | 35 | #ifdef TNT_DEBUG 36 | s << "addr: " << (void *) &A[0] << "\n"; 37 | #endif 38 | s << N << "\n"; 39 | for (int j=0; j 49 | std::istream& operator>>(std::istream &s, Array1D &A) 50 | { 51 | int N; 52 | s >> N; 53 | 54 | Array1D B(N); 55 | for (int i=0; i> B[i]; 57 | A = B; 58 | return s; 59 | } 60 | 61 | 62 | 63 | template 64 | Array1D operator+(const Array1D &A, const Array1D &B) 65 | { 66 | int n = A.dim1(); 67 | 68 | if (B.dim1() != n ) 69 | return Array1D(); 70 | 71 | else 72 | { 73 | Array1D C(n); 74 | 75 | for (int i=0; i 86 | Array1D operator-(const Array1D &A, const Array1D &B) 87 | { 88 | int n = A.dim1(); 89 | 90 | if (B.dim1() != n ) 91 | return Array1D(); 92 | 93 | else 94 | { 95 | Array1D C(n); 96 | 97 | for (int i=0; i 107 | Array1D operator*(const Array1D &A, const Array1D &B) 108 | { 109 | int n = A.dim1(); 110 | 111 | if (B.dim1() != n ) 112 | return Array1D(); 113 | 114 | else 115 | { 116 | Array1D C(n); 117 | 118 | for (int i=0; i 128 | Array1D operator/(const Array1D &A, const Array1D &B) 129 | { 130 | int n = A.dim1(); 131 | 132 | if (B.dim1() != n ) 133 | return Array1D(); 134 | 135 | else 136 | { 137 | Array1D C(n); 138 | 139 | for (int i=0; i 156 | Array1D& operator+=(Array1D &A, const Array1D &B) 157 | { 158 | int n = A.dim1(); 159 | 160 | if (B.dim1() == n) 161 | { 162 | for (int i=0; i 174 | Array1D& operator-=(Array1D &A, const Array1D &B) 175 | { 176 | int n = A.dim1(); 177 | 178 | if (B.dim1() == n) 179 | { 180 | for (int i=0; i 191 | Array1D& operator*=(Array1D &A, const Array1D &B) 192 | { 193 | int n = A.dim1(); 194 | 195 | if (B.dim1() == n) 196 | { 197 | for (int i=0; i 209 | Array1D& operator/=(Array1D &A, const Array1D &B) 210 | { 211 | int n = A.dim1(); 212 | 213 | if (B.dim1() == n) 214 | { 215 | for (int i=0; i 26 | #include 27 | #ifdef TNT_BOUNDS_CHECK 28 | #include 29 | #endif 30 | 31 | #include "tnt_array1d.h" 32 | 33 | namespace TNT 34 | { 35 | 36 | template 37 | class Array2D 38 | { 39 | 40 | 41 | private: 42 | 43 | 44 | 45 | Array1D data_; 46 | Array1D v_; 47 | int m_; 48 | int n_; 49 | 50 | public: 51 | 52 | typedef T value_type; 53 | Array2D(); 54 | Array2D(int m, int n); 55 | Array2D(int m, int n, T *a); 56 | Array2D(int m, int n, const T &a); 57 | inline Array2D(const Array2D &A); 58 | inline operator T**(); 59 | inline operator const T**(); 60 | inline Array2D & operator=(const T &a); 61 | inline Array2D & operator=(const Array2D &A); 62 | inline Array2D & ref(const Array2D &A); 63 | Array2D copy() const; 64 | Array2D & inject(const Array2D & A); 65 | inline T* operator[](int i); 66 | inline const T* operator[](int i) const; 67 | inline int dim1() const; 68 | inline int dim2() const; 69 | ~Array2D(); 70 | 71 | /* extended interface (not part of the standard) */ 72 | 73 | 74 | inline int ref_count(); 75 | inline int ref_count_data(); 76 | inline int ref_count_dim1(); 77 | Array2D subarray(int i0, int i1, int j0, int j1); 78 | 79 | }; 80 | 81 | 82 | template 83 | Array2D::Array2D() : data_(), v_(), m_(0), n_(0) {} 84 | 85 | template 86 | Array2D::Array2D(const Array2D &A) : data_(A.data_), v_(A.v_), 87 | m_(A.m_), n_(A.n_) {} 88 | 89 | 90 | 91 | 92 | template 93 | Array2D::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n) 94 | { 95 | if (m>0 && n>0) 96 | { 97 | T* p = &(data_[0]); 98 | for (int i=0; i 109 | Array2D::Array2D(int m, int n, const T &val) : data_(m*n), v_(m), 110 | m_(m), n_(n) 111 | { 112 | if (m>0 && n>0) 113 | { 114 | data_ = val; 115 | T* p = &(data_[0]); 116 | for (int i=0; i 125 | Array2D::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n) 126 | { 127 | if (m>0 && n>0) 128 | { 129 | T* p = &(data_[0]); 130 | 131 | for (int i=0; i 141 | inline T* Array2D::operator[](int i) 142 | { 143 | #ifdef TNT_BOUNDS_CHECK 144 | assert(i >= 0); 145 | assert(i < m_); 146 | #endif 147 | 148 | return v_[i]; 149 | 150 | } 151 | 152 | 153 | template 154 | inline const T* Array2D::operator[](int i) const 155 | { 156 | #ifdef TNT_BOUNDS_CHECK 157 | assert(i >= 0); 158 | assert(i < m_); 159 | #endif 160 | 161 | return v_[i]; 162 | 163 | } 164 | 165 | template 166 | Array2D & Array2D::operator=(const T &a) 167 | { 168 | /* non-optimzied, but will work with subarrays in future verions */ 169 | 170 | for (int i=0; i 180 | Array2D Array2D::copy() const 181 | { 182 | Array2D A(m_, n_); 183 | 184 | for (int i=0; i 194 | Array2D & Array2D::inject(const Array2D &A) 195 | { 196 | if (A.m_ == m_ && A.n_ == n_) 197 | { 198 | for (int i=0; i 209 | Array2D & Array2D::ref(const Array2D &A) 210 | { 211 | if (this != &A) 212 | { 213 | v_ = A.v_; 214 | data_ = A.data_; 215 | m_ = A.m_; 216 | n_ = A.n_; 217 | 218 | } 219 | return *this; 220 | } 221 | 222 | 223 | 224 | template 225 | Array2D & Array2D::operator=(const Array2D &A) 226 | { 227 | return ref(A); 228 | } 229 | 230 | template 231 | inline int Array2D::dim1() const { return m_; } 232 | 233 | template 234 | inline int Array2D::dim2() const { return n_; } 235 | 236 | 237 | template 238 | Array2D::~Array2D() {} 239 | 240 | 241 | 242 | 243 | template 244 | inline Array2D::operator T**() 245 | { 246 | return &(v_[0]); 247 | } 248 | template 249 | inline Array2D::operator const T**() 250 | { 251 | return &(v_[0]); 252 | } 253 | 254 | /* ............... extended interface ............... */ 255 | /** 256 | Create a new view to a subarray defined by the boundaries 257 | [i0][i0] and [i1][j1]. The size of the subarray is 258 | (i1-i0) by (j1-j0). If either of these lengths are zero 259 | or negative, the subarray view is null. 260 | 261 | */ 262 | template 263 | Array2D Array2D::subarray(int i0, int i1, int j0, int j1) 264 | { 265 | Array2D A; 266 | int m = i1-i0+1; 267 | int n = j1-j0+1; 268 | 269 | /* if either length is zero or negative, this is an invalide 270 | subarray. return a null view. 271 | */ 272 | if (m<1 || n<1) 273 | return A; 274 | 275 | A.data_ = data_; 276 | A.m_ = m; 277 | A.n_ = n; 278 | A.v_ = Array1D(m); 279 | T* p = &(data_[0]) + i0 * n_ + j0; 280 | for (int i=0; i 289 | inline int Array2D::ref_count() 290 | { 291 | return ref_count_data(); 292 | } 293 | 294 | 295 | 296 | template 297 | inline int Array2D::ref_count_data() 298 | { 299 | return data_.ref_count(); 300 | } 301 | 302 | template 303 | inline int Array2D::ref_count_dim1() 304 | { 305 | return v_.ref_count(); 306 | } 307 | 308 | 309 | 310 | 311 | } /* namespace TNT */ 312 | 313 | #endif 314 | /* TNT_ARRAY2D_H */ 315 | 316 | -------------------------------------------------------------------------------- /src/TNT/tnt_array2d_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_ARRAY2D_UTILS_H 22 | #define TNT_ARRAY2D_UTILS_H 23 | 24 | #include 25 | #include 26 | 27 | namespace TNT 28 | { 29 | 30 | 31 | template 32 | std::ostream& operator<<(std::ostream &s, const Array2D &A) 33 | { 34 | int M=A.dim1(); 35 | int N=A.dim2(); 36 | 37 | s << M << " " << N << "\n"; 38 | 39 | for (int i=0; i 53 | std::istream& operator>>(std::istream &s, Array2D &A) 54 | { 55 | 56 | int M, N; 57 | 58 | s >> M >> N; 59 | 60 | Array2D B(M,N); 61 | 62 | for (int i=0; i> B[i][j]; 67 | } 68 | } 69 | 70 | A = B; 71 | return s; 72 | } 73 | 74 | 75 | template 76 | Array2D operator+(const Array2D &A, const Array2D &B) 77 | { 78 | int m = A.dim1(); 79 | int n = A.dim2(); 80 | 81 | if (B.dim1() != m || B.dim2() != n ) 82 | return Array2D(); 83 | 84 | else 85 | { 86 | Array2D C(m,n); 87 | 88 | for (int i=0; i 98 | Array2D operator-(const Array2D &A, const Array2D &B) 99 | { 100 | int m = A.dim1(); 101 | int n = A.dim2(); 102 | 103 | if (B.dim1() != m || B.dim2() != n ) 104 | return Array2D(); 105 | 106 | else 107 | { 108 | Array2D C(m,n); 109 | 110 | for (int i=0; i 121 | Array2D operator*(const Array2D &A, const Array2D &B) 122 | { 123 | int m = A.dim1(); 124 | int n = A.dim2(); 125 | 126 | if (B.dim1() != m || B.dim2() != n ) 127 | return Array2D(); 128 | 129 | else 130 | { 131 | Array2D C(m,n); 132 | 133 | for (int i=0; i 146 | Array2D operator/(const Array2D &A, const Array2D &B) 147 | { 148 | int m = A.dim1(); 149 | int n = A.dim2(); 150 | 151 | if (B.dim1() != m || B.dim2() != n ) 152 | return Array2D(); 153 | 154 | else 155 | { 156 | Array2D C(m,n); 157 | 158 | for (int i=0; i 172 | Array2D& operator+=(Array2D &A, const Array2D &B) 173 | { 174 | int m = A.dim1(); 175 | int n = A.dim2(); 176 | 177 | if (B.dim1() == m || B.dim2() == n ) 178 | { 179 | for (int i=0; i 191 | Array2D& operator-=(Array2D &A, const Array2D &B) 192 | { 193 | int m = A.dim1(); 194 | int n = A.dim2(); 195 | 196 | if (B.dim1() == m || B.dim2() == n ) 197 | { 198 | for (int i=0; i 210 | Array2D& operator*=(Array2D &A, const Array2D &B) 211 | { 212 | int m = A.dim1(); 213 | int n = A.dim2(); 214 | 215 | if (B.dim1() == m || B.dim2() == n ) 216 | { 217 | for (int i=0; i 231 | Array2D& operator/=(Array2D &A, const Array2D &B) 232 | { 233 | int m = A.dim1(); 234 | int n = A.dim2(); 235 | 236 | if (B.dim1() == m || B.dim2() == n ) 237 | { 238 | for (int i=0; i 261 | Array2D matmult(const Array2D &A, const Array2D &B) 262 | { 263 | if (A.dim2() != B.dim1()) 264 | return Array2D(); 265 | 266 | int M = A.dim1(); 267 | int N = A.dim2(); 268 | int K = B.dim2(); 269 | 270 | Array2D C(M,K); 271 | 272 | for (int i=0; i 26 | #include 27 | #ifdef TNT_BOUNDS_CHECK 28 | #include 29 | #endif 30 | 31 | #include "tnt_array1d.h" 32 | #include "tnt_array2d.h" 33 | 34 | namespace TNT 35 | { 36 | 37 | template 38 | class Array3D 39 | { 40 | 41 | 42 | private: 43 | Array1D data_; 44 | Array2D v_; 45 | int m_; 46 | int n_; 47 | int g_; 48 | 49 | 50 | public: 51 | 52 | typedef T value_type; 53 | 54 | Array3D(); 55 | Array3D(int m, int n, int g); 56 | Array3D(int m, int n, int g, T val); 57 | Array3D(int m, int n, int g, T *a); 58 | 59 | inline operator T***(); 60 | inline operator const T***(); 61 | inline Array3D(const Array3D &A); 62 | inline Array3D & operator=(const T &a); 63 | inline Array3D & operator=(const Array3D &A); 64 | inline Array3D & ref(const Array3D &A); 65 | Array3D copy() const; 66 | Array3D & inject(const Array3D & A); 67 | 68 | inline T** operator[](int i); 69 | inline const T* const * operator[](int i) const; 70 | inline int dim1() const; 71 | inline int dim2() const; 72 | inline int dim3() const; 73 | ~Array3D(); 74 | 75 | /* extended interface */ 76 | 77 | inline int ref_count(){ return data_.ref_count(); } 78 | Array3D subarray(int i0, int i1, int j0, int j1, 79 | int k0, int k1); 80 | }; 81 | 82 | template 83 | Array3D::Array3D() : data_(), v_(), m_(0), n_(0) {} 84 | 85 | template 86 | Array3D::Array3D(const Array3D &A) : data_(A.data_), 87 | v_(A.v_), m_(A.m_), n_(A.n_), g_(A.g_) 88 | { 89 | } 90 | 91 | 92 | 93 | template 94 | Array3D::Array3D(int m, int n, int g) : data_(m*n*g), v_(m,n), 95 | m_(m), n_(n), g_(g) 96 | { 97 | 98 | if (m>0 && n>0 && g>0) 99 | { 100 | T* p = & (data_[0]); 101 | int ng = n_*g_; 102 | 103 | for (int i=0; i 115 | Array3D::Array3D(int m, int n, int g, T val) : data_(m*n*g, val), 116 | v_(m,n), m_(m), n_(n), g_(g) 117 | { 118 | if (m>0 && n>0 && g>0) 119 | { 120 | 121 | T* p = & (data_[0]); 122 | int ng = n_*g_; 123 | 124 | for (int i=0; i 136 | Array3D::Array3D(int m, int n, int g, T* a) : 137 | data_(m*n*g, a), v_(m,n), m_(m), n_(n), g_(g) 138 | { 139 | 140 | if (m>0 && n>0 && g>0) 141 | { 142 | T* p = & (data_[0]); 143 | int ng = n_*g_; 144 | 145 | for (int i=0; i 157 | inline T** Array3D::operator[](int i) 158 | { 159 | #ifdef TNT_BOUNDS_CHECK 160 | assert(i >= 0); 161 | assert(i < m_); 162 | #endif 163 | 164 | return v_[i]; 165 | 166 | } 167 | 168 | template 169 | inline const T* const * Array3D::operator[](int i) const 170 | { return v_[i]; } 171 | 172 | template 173 | Array3D & Array3D::operator=(const T &a) 174 | { 175 | for (int i=0; i 184 | Array3D Array3D::copy() const 185 | { 186 | Array3D A(m_, n_, g_); 187 | for (int i=0; i 197 | Array3D & Array3D::inject(const Array3D &A) 198 | { 199 | if (A.m_ == m_ && A.n_ == n_ && A.g_ == g_) 200 | 201 | for (int i=0; i 212 | Array3D & Array3D::ref(const Array3D &A) 213 | { 214 | if (this != &A) 215 | { 216 | m_ = A.m_; 217 | n_ = A.n_; 218 | g_ = A.g_; 219 | v_ = A.v_; 220 | data_ = A.data_; 221 | } 222 | return *this; 223 | } 224 | 225 | template 226 | Array3D & Array3D::operator=(const Array3D &A) 227 | { 228 | return ref(A); 229 | } 230 | 231 | 232 | template 233 | inline int Array3D::dim1() const { return m_; } 234 | 235 | template 236 | inline int Array3D::dim2() const { return n_; } 237 | 238 | template 239 | inline int Array3D::dim3() const { return g_; } 240 | 241 | 242 | 243 | template 244 | Array3D::~Array3D() {} 245 | 246 | template 247 | inline Array3D::operator T***() 248 | { 249 | return v_; 250 | } 251 | 252 | 253 | template 254 | inline Array3D::operator const T***() 255 | { 256 | return v_; 257 | } 258 | 259 | /* extended interface */ 260 | template 261 | Array3D Array3D::subarray(int i0, int i1, int j0, 262 | int j1, int k0, int k1) 263 | { 264 | 265 | /* check that ranges are valid. */ 266 | if (!( 0 <= i0 && i0 <= i1 && i1 < m_ && 267 | 0 <= j0 && j0 <= j1 && j1 < n_ && 268 | 0 <= k0 && k0 <= k1 && k1 < g_)) 269 | return Array3D(); /* null array */ 270 | 271 | 272 | Array3D A; 273 | A.data_ = data_; 274 | A.m_ = i1-i0+1; 275 | A.n_ = j1-j0+1; 276 | A.g_ = k1-k0+1; 277 | A.v_ = Array2D(A.m_,A.n_); 278 | T* p = &(data_[0]) + i0*n_*g_ + j0*g_ + k0; 279 | 280 | for (int i=0; i 7 | #include 8 | 9 | namespace TNT 10 | { 11 | 12 | 13 | template 14 | std::ostream& operator<<(std::ostream &s, const Array3D &A) 15 | { 16 | int M=A.dim1(); 17 | int N=A.dim2(); 18 | int K=A.dim3(); 19 | 20 | s << M << " " << N << " " << K << "\n"; 21 | 22 | for (int i=0; i 40 | std::istream& operator>>(std::istream &s, Array3D &A) 41 | { 42 | 43 | int M, N, K; 44 | 45 | s >> M >> N >> K; 46 | 47 | Array3D B(M,N,K); 48 | 49 | for (int i=0; i> B[i][j][k]; 56 | } 57 | } 58 | } 59 | 60 | A = B; 61 | return s; 62 | } 63 | 64 | 65 | 66 | template 67 | Array3D operator+(const Array3D &A, const Array3D &B) 68 | { 69 | int m = A.dim1(); 70 | int n = A.dim2(); 71 | int p = A.dim3(); 72 | 73 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 74 | return Array3D(); 75 | 76 | else 77 | { 78 | Array3D C(m,n,p); 79 | 80 | for (int i=0; i 97 | Array3D operator-(const Array3D &A, const Array3D &B) 98 | { 99 | int m = A.dim1(); 100 | int n = A.dim2(); 101 | int p = A.dim3(); 102 | 103 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 104 | return Array3D(); 105 | 106 | else 107 | { 108 | Array3D C(m,n,p); 109 | 110 | for (int i=0; i 129 | Array3D operator*(const Array3D &A, const Array3D &B) 130 | { 131 | int m = A.dim1(); 132 | int n = A.dim2(); 133 | int p = A.dim3(); 134 | 135 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 136 | return Array3D(); 137 | 138 | else 139 | { 140 | Array3D C(m,n,p); 141 | 142 | for (int i=0; i 153 | Array3D operator/(const Array3D &A, const Array3D &B) 154 | { 155 | int m = A.dim1(); 156 | int n = A.dim2(); 157 | int p = A.dim3(); 158 | 159 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 160 | return Array3D(); 161 | 162 | else 163 | { 164 | Array3D C(m,n,p); 165 | 166 | for (int i=0; i 178 | Array3D& operator+=(Array3D &A, const Array3D &B) 179 | { 180 | int m = A.dim1(); 181 | int n = A.dim2(); 182 | int p = A.dim3(); 183 | 184 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 185 | { 186 | for (int i=0; i 196 | Array3D& operator-=(Array3D &A, const Array3D &B) 197 | { 198 | int m = A.dim1(); 199 | int n = A.dim2(); 200 | int p = A.dim3(); 201 | 202 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 203 | { 204 | for (int i=0; i 214 | Array3D& operator*=(Array3D &A, const Array3D &B) 215 | { 216 | int m = A.dim1(); 217 | int n = A.dim2(); 218 | int p = A.dim3(); 219 | 220 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 221 | { 222 | for (int i=0; i 233 | Array3D& operator/=(Array3D &A, const Array3D &B) 234 | { 235 | int m = A.dim1(); 236 | int n = A.dim2(); 237 | int p = A.dim3(); 238 | 239 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 240 | { 241 | for (int i=0; i 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | 33 | #include "tnt_i_refvec.h" 34 | 35 | namespace TNT 36 | { 37 | 38 | template 39 | class Fortran_Array1D 40 | { 41 | 42 | private: 43 | 44 | i_refvec v_; 45 | int n_; 46 | T* data_; /* this normally points to v_.begin(), but 47 | * could also point to a portion (subvector) 48 | * of v_. 49 | */ 50 | 51 | void initialize_(int n); 52 | void copy_(T* p, const T* q, int len) const; 53 | void set_(T* begin, T* end, const T& val); 54 | 55 | 56 | public: 57 | 58 | typedef T value_type; 59 | 60 | 61 | Fortran_Array1D(); 62 | explicit Fortran_Array1D(int n); 63 | Fortran_Array1D(int n, const T &a); 64 | Fortran_Array1D(int n, T *a); 65 | inline Fortran_Array1D(const Fortran_Array1D &A); 66 | inline Fortran_Array1D & operator=(const T &a); 67 | inline Fortran_Array1D & operator=(const Fortran_Array1D &A); 68 | inline Fortran_Array1D & ref(const Fortran_Array1D &A); 69 | Fortran_Array1D copy() const; 70 | Fortran_Array1D & inject(const Fortran_Array1D & A); 71 | inline T& operator()(int i); 72 | inline const T& operator()(int i) const; 73 | inline int dim1() const; 74 | inline int dim() const; 75 | ~Fortran_Array1D(); 76 | 77 | 78 | /* ... extended interface ... */ 79 | 80 | inline int ref_count() const; 81 | inline Fortran_Array1D subarray(int i0, int i1); 82 | 83 | }; 84 | 85 | 86 | 87 | 88 | template 89 | Fortran_Array1D::Fortran_Array1D() : v_(), n_(0), data_(0) {} 90 | 91 | template 92 | Fortran_Array1D::Fortran_Array1D(const Fortran_Array1D &A) : v_(A.v_), n_(A.n_), 93 | data_(A.data_) 94 | { 95 | #ifdef TNT_DEBUG 96 | std::cout << "Created Fortran_Array1D(const Fortran_Array1D &A) \n"; 97 | #endif 98 | 99 | } 100 | 101 | 102 | template 103 | Fortran_Array1D::Fortran_Array1D(int n) : v_(n), n_(n), data_(v_.begin()) 104 | { 105 | #ifdef TNT_DEBUG 106 | std::cout << "Created Fortran_Array1D(int n) \n"; 107 | #endif 108 | } 109 | 110 | template 111 | Fortran_Array1D::Fortran_Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin()) 112 | { 113 | #ifdef TNT_DEBUG 114 | std::cout << "Created Fortran_Array1D(int n, const T& val) \n"; 115 | #endif 116 | set_(data_, data_+ n, val); 117 | 118 | } 119 | 120 | template 121 | Fortran_Array1D::Fortran_Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin()) 122 | { 123 | #ifdef TNT_DEBUG 124 | std::cout << "Created Fortran_Array1D(int n, T* a) \n"; 125 | #endif 126 | } 127 | 128 | template 129 | inline T& Fortran_Array1D::operator()(int i) 130 | { 131 | #ifdef TNT_BOUNDS_CHECK 132 | assert(i>= 1); 133 | assert(i <= n_); 134 | #endif 135 | return data_[i-1]; 136 | } 137 | 138 | template 139 | inline const T& Fortran_Array1D::operator()(int i) const 140 | { 141 | #ifdef TNT_BOUNDS_CHECK 142 | assert(i>= 1); 143 | assert(i <= n_); 144 | #endif 145 | return data_[i-1]; 146 | } 147 | 148 | 149 | 150 | 151 | template 152 | Fortran_Array1D & Fortran_Array1D::operator=(const T &a) 153 | { 154 | set_(data_, data_+n_, a); 155 | return *this; 156 | } 157 | 158 | template 159 | Fortran_Array1D Fortran_Array1D::copy() const 160 | { 161 | Fortran_Array1D A( n_); 162 | copy_(A.data_, data_, n_); 163 | 164 | return A; 165 | } 166 | 167 | 168 | template 169 | Fortran_Array1D & Fortran_Array1D::inject(const Fortran_Array1D &A) 170 | { 171 | if (A.n_ == n_) 172 | copy_(data_, A.data_, n_); 173 | 174 | return *this; 175 | } 176 | 177 | 178 | 179 | 180 | 181 | template 182 | Fortran_Array1D & Fortran_Array1D::ref(const Fortran_Array1D &A) 183 | { 184 | if (this != &A) 185 | { 186 | v_ = A.v_; /* operator= handles the reference counting. */ 187 | n_ = A.n_; 188 | data_ = A.data_; 189 | 190 | } 191 | return *this; 192 | } 193 | 194 | template 195 | Fortran_Array1D & Fortran_Array1D::operator=(const Fortran_Array1D &A) 196 | { 197 | return ref(A); 198 | } 199 | 200 | template 201 | inline int Fortran_Array1D::dim1() const { return n_; } 202 | 203 | template 204 | inline int Fortran_Array1D::dim() const { return n_; } 205 | 206 | template 207 | Fortran_Array1D::~Fortran_Array1D() {} 208 | 209 | 210 | /* ............................ exented interface ......................*/ 211 | 212 | template 213 | inline int Fortran_Array1D::ref_count() const 214 | { 215 | return v_.ref_count(); 216 | } 217 | 218 | template 219 | inline Fortran_Array1D Fortran_Array1D::subarray(int i0, int i1) 220 | { 221 | #ifdef TNT_DEBUG 222 | std::cout << "entered subarray. \n"; 223 | #endif 224 | if ((i0 > 0) && (i1 < n_) || (i0 <= i1)) 225 | { 226 | Fortran_Array1D X(*this); /* create a new instance of this array. */ 227 | X.n_ = i1-i0+1; 228 | X.data_ += i0; 229 | 230 | return X; 231 | } 232 | else 233 | { 234 | #ifdef TNT_DEBUG 235 | std::cout << "subarray: null return.\n"; 236 | #endif 237 | return Fortran_Array1D(); 238 | } 239 | } 240 | 241 | 242 | /* private internal functions */ 243 | 244 | 245 | template 246 | void Fortran_Array1D::set_(T* begin, T* end, const T& a) 247 | { 248 | for (T* p=begin; p 254 | void Fortran_Array1D::copy_(T* p, const T* q, int len) const 255 | { 256 | T *end = p + len; 257 | while (p 24 | 25 | namespace TNT 26 | { 27 | 28 | 29 | /** 30 | Write an array to a character outstream. Output format is one that can 31 | be read back in via the in-stream operator: one integer 32 | denoting the array dimension (n), followed by n elements, 33 | one per line. 34 | 35 | */ 36 | template 37 | std::ostream& operator<<(std::ostream &s, const Fortran_Array1D &A) 38 | { 39 | int N=A.dim1(); 40 | 41 | s << N << "\n"; 42 | for (int j=1; j<=N; j++) 43 | { 44 | s << A(j) << "\n"; 45 | } 46 | s << "\n"; 47 | 48 | return s; 49 | } 50 | 51 | /** 52 | Read an array from a character stream. Input format 53 | is one integer, denoting the dimension (n), followed 54 | by n whitespace-separated elments. Newlines are ignored 55 | 56 |

57 | Note: the array being read into references new memory 58 | storage. If the intent is to fill an existing conformant 59 | array, use cin >> B; A.inject(B) ); 60 | instead or read the elements in one-a-time by hand. 61 | 62 | @param s the charater to read from (typically std::in) 63 | @param A the array to read into. 64 | */ 65 | template 66 | std::istream& operator>>(std::istream &s, Fortran_Array1D &A) 67 | { 68 | int N; 69 | s >> N; 70 | 71 | Fortran_Array1D B(N); 72 | for (int i=1; i<=N; i++) 73 | s >> B(i); 74 | A = B; 75 | return s; 76 | } 77 | 78 | 79 | template 80 | Fortran_Array1D operator+(const Fortran_Array1D &A, const Fortran_Array1D &B) 81 | { 82 | int n = A.dim1(); 83 | 84 | if (B.dim1() != n ) 85 | return Fortran_Array1D(); 86 | 87 | else 88 | { 89 | Fortran_Array1D C(n); 90 | 91 | for (int i=1; i<=n; i++) 92 | { 93 | C(i) = A(i) + B(i); 94 | } 95 | return C; 96 | } 97 | } 98 | 99 | 100 | 101 | template 102 | Fortran_Array1D operator-(const Fortran_Array1D &A, const Fortran_Array1D &B) 103 | { 104 | int n = A.dim1(); 105 | 106 | if (B.dim1() != n ) 107 | return Fortran_Array1D(); 108 | 109 | else 110 | { 111 | Fortran_Array1D C(n); 112 | 113 | for (int i=1; i<=n; i++) 114 | { 115 | C(i) = A(i) - B(i); 116 | } 117 | return C; 118 | } 119 | } 120 | 121 | 122 | template 123 | Fortran_Array1D operator*(const Fortran_Array1D &A, const Fortran_Array1D &B) 124 | { 125 | int n = A.dim1(); 126 | 127 | if (B.dim1() != n ) 128 | return Fortran_Array1D(); 129 | 130 | else 131 | { 132 | Fortran_Array1D C(n); 133 | 134 | for (int i=1; i<=n; i++) 135 | { 136 | C(i) = A(i) * B(i); 137 | } 138 | return C; 139 | } 140 | } 141 | 142 | 143 | template 144 | Fortran_Array1D operator/(const Fortran_Array1D &A, const Fortran_Array1D &B) 145 | { 146 | int n = A.dim1(); 147 | 148 | if (B.dim1() != n ) 149 | return Fortran_Array1D(); 150 | 151 | else 152 | { 153 | Fortran_Array1D C(n); 154 | 155 | for (int i=1; i<=n; i++) 156 | { 157 | C(i) = A(i) / B(i); 158 | } 159 | return C; 160 | } 161 | } 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | template 172 | Fortran_Array1D& operator+=(Fortran_Array1D &A, const Fortran_Array1D &B) 173 | { 174 | int n = A.dim1(); 175 | 176 | if (B.dim1() == n) 177 | { 178 | for (int i=1; i<=n; i++) 179 | { 180 | A(i) += B(i); 181 | } 182 | } 183 | return A; 184 | } 185 | 186 | 187 | 188 | 189 | template 190 | Fortran_Array1D& operator-=(Fortran_Array1D &A, const Fortran_Array1D &B) 191 | { 192 | int n = A.dim1(); 193 | 194 | if (B.dim1() == n) 195 | { 196 | for (int i=1; i<=n; i++) 197 | { 198 | A(i) -= B(i); 199 | } 200 | } 201 | return A; 202 | } 203 | 204 | 205 | 206 | template 207 | Fortran_Array1D& operator*=(Fortran_Array1D &A, const Fortran_Array1D &B) 208 | { 209 | int n = A.dim1(); 210 | 211 | if (B.dim1() == n) 212 | { 213 | for (int i=1; i<=n; i++) 214 | { 215 | A(i) *= B(i); 216 | } 217 | } 218 | return A; 219 | } 220 | 221 | 222 | 223 | 224 | template 225 | Fortran_Array1D& operator/=(Fortran_Array1D &A, const Fortran_Array1D &B) 226 | { 227 | int n = A.dim1(); 228 | 229 | if (B.dim1() == n) 230 | { 231 | for (int i=1; i<=n; i++) 232 | { 233 | A(i) /= B(i); 234 | } 235 | } 236 | return A; 237 | } 238 | 239 | 240 | } // namespace TNT 241 | 242 | #endif 243 | -------------------------------------------------------------------------------- /src/TNT/tnt_fortran_array2d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT): Two-dimensional Fortran numerical array 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_FORTRAN_ARRAY2D_H 23 | #define TNT_FORTRAN_ARRAY2D_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | #include "tnt_i_refvec.h" 33 | 34 | namespace TNT 35 | { 36 | 37 | template 38 | class Fortran_Array2D 39 | { 40 | 41 | 42 | private: 43 | i_refvec v_; 44 | int m_; 45 | int n_; 46 | T* data_; 47 | 48 | 49 | void initialize_(int n); 50 | void copy_(T* p, const T* q, int len); 51 | void set_(T* begin, T* end, const T& val); 52 | 53 | public: 54 | 55 | typedef T value_type; 56 | 57 | Fortran_Array2D(); 58 | Fortran_Array2D(int m, int n); 59 | Fortran_Array2D(int m, int n, T *a); 60 | Fortran_Array2D(int m, int n, const T &a); 61 | inline Fortran_Array2D(const Fortran_Array2D &A); 62 | inline Fortran_Array2D & operator=(const T &a); 63 | inline Fortran_Array2D & operator=(const Fortran_Array2D &A); 64 | inline Fortran_Array2D & ref(const Fortran_Array2D &A); 65 | Fortran_Array2D copy() const; 66 | Fortran_Array2D & inject(const Fortran_Array2D & A); 67 | inline T& operator()(int i, int j); 68 | inline const T& operator()(int i, int j) const ; 69 | inline int dim1() const; 70 | inline int dim2() const; 71 | ~Fortran_Array2D(); 72 | 73 | /* extended interface */ 74 | 75 | inline int ref_count() const; 76 | 77 | }; 78 | 79 | template 80 | Fortran_Array2D::Fortran_Array2D() : v_(), m_(0), n_(0), data_(0) {} 81 | 82 | 83 | template 84 | Fortran_Array2D::Fortran_Array2D(const Fortran_Array2D &A) : v_(A.v_), 85 | m_(A.m_), n_(A.n_), data_(A.data_) {} 86 | 87 | 88 | 89 | template 90 | Fortran_Array2D::Fortran_Array2D(int m, int n) : v_(m*n), m_(m), n_(n), 91 | data_(v_.begin()) {} 92 | 93 | template 94 | Fortran_Array2D::Fortran_Array2D(int m, int n, const T &val) : 95 | v_(m*n), m_(m), n_(n), data_(v_.begin()) 96 | { 97 | set_(data_, data_+m*n, val); 98 | } 99 | 100 | 101 | template 102 | Fortran_Array2D::Fortran_Array2D(int m, int n, T *a) : v_(a), 103 | m_(m), n_(n), data_(v_.begin()) {} 104 | 105 | 106 | 107 | 108 | template 109 | inline T& Fortran_Array2D::operator()(int i, int j) 110 | { 111 | #ifdef TNT_BOUNDS_CHECK 112 | assert(i >= 1); 113 | assert(i <= m_); 114 | assert(j >= 1); 115 | assert(j <= n_); 116 | #endif 117 | 118 | return v_[ (j-1)*m_ + (i-1) ]; 119 | 120 | } 121 | 122 | template 123 | inline const T& Fortran_Array2D::operator()(int i, int j) const 124 | { 125 | #ifdef TNT_BOUNDS_CHECK 126 | assert(i >= 1); 127 | assert(i <= m_); 128 | assert(j >= 1); 129 | assert(j <= n_); 130 | #endif 131 | 132 | return v_[ (j-1)*m_ + (i-1) ]; 133 | 134 | } 135 | 136 | 137 | template 138 | Fortran_Array2D & Fortran_Array2D::operator=(const T &a) 139 | { 140 | set_(data_, data_+m_*n_, a); 141 | return *this; 142 | } 143 | 144 | template 145 | Fortran_Array2D Fortran_Array2D::copy() const 146 | { 147 | 148 | Fortran_Array2D B(m_,n_); 149 | 150 | B.inject(*this); 151 | return B; 152 | } 153 | 154 | 155 | template 156 | Fortran_Array2D & Fortran_Array2D::inject(const Fortran_Array2D &A) 157 | { 158 | if (m_ == A.m_ && n_ == A.n_) 159 | copy_(data_, A.data_, m_*n_); 160 | 161 | return *this; 162 | } 163 | 164 | 165 | 166 | template 167 | Fortran_Array2D & Fortran_Array2D::ref(const Fortran_Array2D &A) 168 | { 169 | if (this != &A) 170 | { 171 | v_ = A.v_; 172 | m_ = A.m_; 173 | n_ = A.n_; 174 | data_ = A.data_; 175 | } 176 | return *this; 177 | } 178 | 179 | template 180 | Fortran_Array2D & Fortran_Array2D::operator=(const Fortran_Array2D &A) 181 | { 182 | return ref(A); 183 | } 184 | 185 | template 186 | inline int Fortran_Array2D::dim1() const { return m_; } 187 | 188 | template 189 | inline int Fortran_Array2D::dim2() const { return n_; } 190 | 191 | 192 | template 193 | Fortran_Array2D::~Fortran_Array2D() 194 | { 195 | } 196 | 197 | template 198 | inline int Fortran_Array2D::ref_count() const { return v_.ref_count(); } 199 | 200 | 201 | 202 | 203 | template 204 | void Fortran_Array2D::set_(T* begin, T* end, const T& a) 205 | { 206 | for (T* p=begin; p 212 | void Fortran_Array2D::copy_(T* p, const T* q, int len) 213 | { 214 | T *end = p + len; 215 | while (p 25 | 26 | namespace TNT 27 | { 28 | 29 | 30 | template 31 | std::ostream& operator<<(std::ostream &s, const Fortran_Array2D &A) 32 | { 33 | int M=A.dim1(); 34 | int N=A.dim2(); 35 | 36 | s << M << " " << N << "\n"; 37 | 38 | for (int i=1; i<=M; i++) 39 | { 40 | for (int j=1; j<=N; j++) 41 | { 42 | s << A(i,j) << " "; 43 | } 44 | s << "\n"; 45 | } 46 | 47 | 48 | return s; 49 | } 50 | 51 | template 52 | std::istream& operator>>(std::istream &s, Fortran_Array2D &A) 53 | { 54 | 55 | int M, N; 56 | 57 | s >> M >> N; 58 | 59 | Fortran_Array2D B(M,N); 60 | 61 | for (int i=1; i<=M; i++) 62 | { 63 | for (int j=1; j<=N; j++) 64 | { 65 | s >> B(i,j); 66 | } 67 | } 68 | 69 | A = B; 70 | return s; 71 | } 72 | 73 | 74 | 75 | 76 | template 77 | Fortran_Array2D operator+(const Fortran_Array2D &A, const Fortran_Array2D &B) 78 | { 79 | int m = A.dim1(); 80 | int n = A.dim2(); 81 | 82 | if (B.dim1() != m || B.dim2() != n ) 83 | return Fortran_Array2D(); 84 | 85 | else 86 | { 87 | Fortran_Array2D C(m,n); 88 | 89 | for (int i=1; i<=m; i++) 90 | { 91 | for (int j=1; j<=n; j++) 92 | C(i,j) = A(i,j) + B(i,j); 93 | } 94 | return C; 95 | } 96 | } 97 | 98 | template 99 | Fortran_Array2D operator-(const Fortran_Array2D &A, const Fortran_Array2D &B) 100 | { 101 | int m = A.dim1(); 102 | int n = A.dim2(); 103 | 104 | if (B.dim1() != m || B.dim2() != n ) 105 | return Fortran_Array2D(); 106 | 107 | else 108 | { 109 | Fortran_Array2D C(m,n); 110 | 111 | for (int i=1; i<=m; i++) 112 | { 113 | for (int j=1; j<=n; j++) 114 | C(i,j) = A(i,j) - B(i,j); 115 | } 116 | return C; 117 | } 118 | } 119 | 120 | 121 | template 122 | Fortran_Array2D operator*(const Fortran_Array2D &A, const Fortran_Array2D &B) 123 | { 124 | int m = A.dim1(); 125 | int n = A.dim2(); 126 | 127 | if (B.dim1() != m || B.dim2() != n ) 128 | return Fortran_Array2D(); 129 | 130 | else 131 | { 132 | Fortran_Array2D C(m,n); 133 | 134 | for (int i=1; i<=m; i++) 135 | { 136 | for (int j=1; j<=n; j++) 137 | C(i,j) = A(i,j) * B(i,j); 138 | } 139 | return C; 140 | } 141 | } 142 | 143 | 144 | template 145 | Fortran_Array2D operator/(const Fortran_Array2D &A, const Fortran_Array2D &B) 146 | { 147 | int m = A.dim1(); 148 | int n = A.dim2(); 149 | 150 | if (B.dim1() != m || B.dim2() != n ) 151 | return Fortran_Array2D(); 152 | 153 | else 154 | { 155 | Fortran_Array2D C(m,n); 156 | 157 | for (int i=1; i<=m; i++) 158 | { 159 | for (int j=1; j<=n; j++) 160 | C(i,j) = A(i,j) / B(i,j); 161 | } 162 | return C; 163 | } 164 | } 165 | 166 | 167 | 168 | template 169 | Fortran_Array2D& operator+=(Fortran_Array2D &A, const Fortran_Array2D &B) 170 | { 171 | int m = A.dim1(); 172 | int n = A.dim2(); 173 | 174 | if (B.dim1() == m || B.dim2() == n ) 175 | { 176 | for (int i=1; i<=m; i++) 177 | { 178 | for (int j=1; j<=n; j++) 179 | A(i,j) += B(i,j); 180 | } 181 | } 182 | return A; 183 | } 184 | 185 | template 186 | Fortran_Array2D& operator-=(Fortran_Array2D &A, const Fortran_Array2D &B) 187 | { 188 | int m = A.dim1(); 189 | int n = A.dim2(); 190 | 191 | if (B.dim1() == m || B.dim2() == n ) 192 | { 193 | for (int i=1; i<=m; i++) 194 | { 195 | for (int j=1; j<=n; j++) 196 | A(i,j) -= B(i,j); 197 | } 198 | } 199 | return A; 200 | } 201 | 202 | template 203 | Fortran_Array2D& operator*=(Fortran_Array2D &A, const Fortran_Array2D &B) 204 | { 205 | int m = A.dim1(); 206 | int n = A.dim2(); 207 | 208 | if (B.dim1() == m || B.dim2() == n ) 209 | { 210 | for (int i=1; i<=m; i++) 211 | { 212 | for (int j=1; j<=n; j++) 213 | A(i,j) *= B(i,j); 214 | } 215 | } 216 | return A; 217 | } 218 | 219 | template 220 | Fortran_Array2D& operator/=(Fortran_Array2D &A, const Fortran_Array2D &B) 221 | { 222 | int m = A.dim1(); 223 | int n = A.dim2(); 224 | 225 | if (B.dim1() == m || B.dim2() == n ) 226 | { 227 | for (int i=1; i<=m; i++) 228 | { 229 | for (int j=1; j<=n; j++) 230 | A(i,j) /= B(i,j); 231 | } 232 | } 233 | return A; 234 | } 235 | 236 | } // namespace TNT 237 | 238 | #endif 239 | -------------------------------------------------------------------------------- /src/TNT/tnt_fortran_array3d.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT): Three-dimensional Fortran numerical array 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_FORTRAN_ARRAY3D_H 23 | #define TNT_FORTRAN_ARRAY3D_H 24 | 25 | #include 26 | #include 27 | #ifdef TNT_BOUNDS_CHECK 28 | #include 29 | #endif 30 | #include "tnt_i_refvec.h" 31 | 32 | namespace TNT 33 | { 34 | 35 | template 36 | class Fortran_Array3D 37 | { 38 | 39 | 40 | private: 41 | 42 | 43 | i_refvec v_; 44 | int m_; 45 | int n_; 46 | int k_; 47 | T* data_; 48 | 49 | public: 50 | 51 | typedef T value_type; 52 | 53 | Fortran_Array3D(); 54 | Fortran_Array3D(int m, int n, int k); 55 | Fortran_Array3D(int m, int n, int k, T *a); 56 | Fortran_Array3D(int m, int n, int k, const T &a); 57 | inline Fortran_Array3D(const Fortran_Array3D &A); 58 | inline Fortran_Array3D & operator=(const T &a); 59 | inline Fortran_Array3D & operator=(const Fortran_Array3D &A); 60 | inline Fortran_Array3D & ref(const Fortran_Array3D &A); 61 | Fortran_Array3D copy() const; 62 | Fortran_Array3D & inject(const Fortran_Array3D & A); 63 | inline T& operator()(int i, int j, int k); 64 | inline const T& operator()(int i, int j, int k) const ; 65 | inline int dim1() const; 66 | inline int dim2() const; 67 | inline int dim3() const; 68 | inline int ref_count() const; 69 | ~Fortran_Array3D(); 70 | 71 | 72 | }; 73 | 74 | template 75 | Fortran_Array3D::Fortran_Array3D() : v_(), m_(0), n_(0), k_(0), data_(0) {} 76 | 77 | 78 | template 79 | Fortran_Array3D::Fortran_Array3D(const Fortran_Array3D &A) : 80 | v_(A.v_), m_(A.m_), n_(A.n_), k_(A.k_), data_(A.data_) {} 81 | 82 | 83 | 84 | template 85 | Fortran_Array3D::Fortran_Array3D(int m, int n, int k) : 86 | v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) {} 87 | 88 | 89 | 90 | template 91 | Fortran_Array3D::Fortran_Array3D(int m, int n, int k, const T &val) : 92 | v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) 93 | { 94 | for (T* p = data_; p < data_ + m*n*k; p++) 95 | *p = val; 96 | } 97 | 98 | template 99 | Fortran_Array3D::Fortran_Array3D(int m, int n, int k, T *a) : 100 | v_(a), m_(m), n_(n), k_(k), data_(v_.begin()) {} 101 | 102 | 103 | 104 | 105 | template 106 | inline T& Fortran_Array3D::operator()(int i, int j, int k) 107 | { 108 | #ifdef TNT_BOUNDS_CHECK 109 | assert(i >= 1); 110 | assert(i <= m_); 111 | assert(j >= 1); 112 | assert(j <= n_); 113 | assert(k >= 1); 114 | assert(k <= k_); 115 | #endif 116 | 117 | return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1]; 118 | 119 | } 120 | 121 | template 122 | inline const T& Fortran_Array3D::operator()(int i, int j, int k) const 123 | { 124 | #ifdef TNT_BOUNDS_CHECK 125 | assert(i >= 1); 126 | assert(i <= m_); 127 | assert(j >= 1); 128 | assert(j <= n_); 129 | assert(k >= 1); 130 | assert(k <= k_); 131 | #endif 132 | 133 | return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1]; 134 | } 135 | 136 | 137 | template 138 | Fortran_Array3D & Fortran_Array3D::operator=(const T &a) 139 | { 140 | 141 | T *end = data_ + m_*n_*k_; 142 | 143 | for (T *p=data_; p != end; *p++ = a); 144 | 145 | return *this; 146 | } 147 | 148 | template 149 | Fortran_Array3D Fortran_Array3D::copy() const 150 | { 151 | 152 | Fortran_Array3D B(m_, n_, k_); 153 | B.inject(*this); 154 | return B; 155 | 156 | } 157 | 158 | 159 | template 160 | Fortran_Array3D & Fortran_Array3D::inject(const Fortran_Array3D &A) 161 | { 162 | 163 | if (m_ == A.m_ && n_ == A.n_ && k_ == A.k_) 164 | { 165 | T *p = data_; 166 | T *end = data_ + m_*n_*k_; 167 | const T* q = A.data_; 168 | for (; p < end; *p++ = *q++); 169 | } 170 | return *this; 171 | } 172 | 173 | 174 | 175 | 176 | template 177 | Fortran_Array3D & Fortran_Array3D::ref(const Fortran_Array3D &A) 178 | { 179 | 180 | if (this != &A) 181 | { 182 | v_ = A.v_; 183 | m_ = A.m_; 184 | n_ = A.n_; 185 | k_ = A.k_; 186 | data_ = A.data_; 187 | } 188 | return *this; 189 | } 190 | 191 | template 192 | Fortran_Array3D & Fortran_Array3D::operator=(const Fortran_Array3D &A) 193 | { 194 | return ref(A); 195 | } 196 | 197 | template 198 | inline int Fortran_Array3D::dim1() const { return m_; } 199 | 200 | template 201 | inline int Fortran_Array3D::dim2() const { return n_; } 202 | 203 | template 204 | inline int Fortran_Array3D::dim3() const { return k_; } 205 | 206 | 207 | template 208 | inline int Fortran_Array3D::ref_count() const 209 | { 210 | return v_.ref_count(); 211 | } 212 | 213 | template 214 | Fortran_Array3D::~Fortran_Array3D() 215 | { 216 | } 217 | 218 | 219 | } /* namespace TNT */ 220 | 221 | #endif 222 | /* TNT_FORTRAN_ARRAY3D_H */ 223 | 224 | -------------------------------------------------------------------------------- /src/TNT/tnt_fortran_array3d_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_FORTRAN_ARRAY3D_UTILS_H 22 | #define TNT_FORTRAN_ARRAY3D_UTILS_H 23 | 24 | #include 25 | #include 26 | 27 | namespace TNT 28 | { 29 | 30 | 31 | template 32 | std::ostream& operator<<(std::ostream &s, const Fortran_Array3D &A) 33 | { 34 | int M=A.dim1(); 35 | int N=A.dim2(); 36 | int K=A.dim3(); 37 | 38 | s << M << " " << N << " " << K << "\n"; 39 | 40 | for (int i=1; i<=M; i++) 41 | { 42 | for (int j=1; j<=N; j++) 43 | { 44 | for (int k=1; k<=K; k++) 45 | { 46 | s << A(i,j,k) << " "; 47 | } 48 | s << "\n"; 49 | } 50 | s << "\n"; 51 | } 52 | 53 | 54 | return s; 55 | } 56 | 57 | template 58 | std::istream& operator>>(std::istream &s, Fortran_Array3D &A) 59 | { 60 | 61 | int M, N, K; 62 | 63 | s >> M >> N >> K; 64 | 65 | Fortran_Array3D B(M,N,K); 66 | 67 | for (int i=1; i<=M; i++) 68 | { 69 | for (int j=1; j<=N; j++) 70 | { 71 | for (int k=1; k<=K; k++) 72 | { 73 | s >> B(i,j,k); 74 | } 75 | } 76 | } 77 | 78 | A = B; 79 | return s; 80 | } 81 | 82 | 83 | template 84 | Fortran_Array3D operator+(const Fortran_Array3D &A, const Fortran_Array3D &B) 85 | { 86 | int m = A.dim1(); 87 | int n = A.dim2(); 88 | int p = A.dim3(); 89 | 90 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 91 | return Fortran_Array3D(); 92 | 93 | else 94 | { 95 | Fortran_Array3D C(m,n,p); 96 | 97 | for (int i=1; i<=m; i++) 98 | for (int j=1; j<=n; j++) 99 | for (int k=1; k<=p; k++) 100 | C(i,j,k) = A(i,j,k)+ B(i,j,k); 101 | 102 | return C; 103 | } 104 | } 105 | 106 | 107 | template 108 | Fortran_Array3D operator-(const Fortran_Array3D &A, const Fortran_Array3D &B) 109 | { 110 | int m = A.dim1(); 111 | int n = A.dim2(); 112 | int p = A.dim3(); 113 | 114 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 115 | return Fortran_Array3D(); 116 | 117 | else 118 | { 119 | Fortran_Array3D C(m,n,p); 120 | 121 | for (int i=1; i<=m; i++) 122 | for (int j=1; j<=n; j++) 123 | for (int k=1; k<=p; k++) 124 | C(i,j,k) = A(i,j,k)- B(i,j,k); 125 | 126 | return C; 127 | } 128 | } 129 | 130 | 131 | template 132 | Fortran_Array3D operator*(const Fortran_Array3D &A, const Fortran_Array3D &B) 133 | { 134 | int m = A.dim1(); 135 | int n = A.dim2(); 136 | int p = A.dim3(); 137 | 138 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 139 | return Fortran_Array3D(); 140 | 141 | else 142 | { 143 | Fortran_Array3D C(m,n,p); 144 | 145 | for (int i=1; i<=m; i++) 146 | for (int j=1; j<=n; j++) 147 | for (int k=1; k<=p; k++) 148 | C(i,j,k) = A(i,j,k)* B(i,j,k); 149 | 150 | return C; 151 | } 152 | } 153 | 154 | 155 | template 156 | Fortran_Array3D operator/(const Fortran_Array3D &A, const Fortran_Array3D &B) 157 | { 158 | int m = A.dim1(); 159 | int n = A.dim2(); 160 | int p = A.dim3(); 161 | 162 | if (B.dim1() != m || B.dim2() != n || B.dim3() != p ) 163 | return Fortran_Array3D(); 164 | 165 | else 166 | { 167 | Fortran_Array3D C(m,n,p); 168 | 169 | for (int i=1; i<=m; i++) 170 | for (int j=1; j<=n; j++) 171 | for (int k=1; k<=p; k++) 172 | C(i,j,k) = A(i,j,k)/ B(i,j,k); 173 | 174 | return C; 175 | } 176 | } 177 | 178 | 179 | template 180 | Fortran_Array3D& operator+=(Fortran_Array3D &A, const Fortran_Array3D &B) 181 | { 182 | int m = A.dim1(); 183 | int n = A.dim2(); 184 | int p = A.dim3(); 185 | 186 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 187 | { 188 | for (int i=1; i<=m; i++) 189 | for (int j=1; j<=n; j++) 190 | for (int k=1; k<=p; k++) 191 | A(i,j,k) += B(i,j,k); 192 | } 193 | 194 | return A; 195 | } 196 | 197 | 198 | template 199 | Fortran_Array3D& operator-=(Fortran_Array3D &A, const Fortran_Array3D &B) 200 | { 201 | int m = A.dim1(); 202 | int n = A.dim2(); 203 | int p = A.dim3(); 204 | 205 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 206 | { 207 | for (int i=1; i<=m; i++) 208 | for (int j=1; j<=n; j++) 209 | for (int k=1; k<=p; k++) 210 | A(i,j,k) -= B(i,j,k); 211 | } 212 | 213 | return A; 214 | } 215 | 216 | 217 | template 218 | Fortran_Array3D& operator*=(Fortran_Array3D &A, const Fortran_Array3D &B) 219 | { 220 | int m = A.dim1(); 221 | int n = A.dim2(); 222 | int p = A.dim3(); 223 | 224 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 225 | { 226 | for (int i=1; i<=m; i++) 227 | for (int j=1; j<=n; j++) 228 | for (int k=1; k<=p; k++) 229 | A(i,j,k) *= B(i,j,k); 230 | } 231 | 232 | return A; 233 | } 234 | 235 | 236 | template 237 | Fortran_Array3D& operator/=(Fortran_Array3D &A, const Fortran_Array3D &B) 238 | { 239 | int m = A.dim1(); 240 | int n = A.dim2(); 241 | int p = A.dim3(); 242 | 243 | if (B.dim1() == m && B.dim2() == n && B.dim3() == p ) 244 | { 245 | for (int i=1; i<=m; i++) 246 | for (int j=1; j<=n; j++) 247 | for (int k=1; k<=p; k++) 248 | A(i,j,k) /= B(i,j,k); 249 | } 250 | 251 | return A; 252 | } 253 | 254 | 255 | } // namespace TNT 256 | 257 | #endif 258 | -------------------------------------------------------------------------------- /src/TNT/tnt_i_refvec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_I_REFVEC_H 23 | #define TNT_I_REFVEC_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef TNT_BOUNDS_CHECK 29 | #include 30 | #endif 31 | 32 | #ifndef NULL 33 | #define NULL 0 34 | #endif 35 | 36 | namespace TNT 37 | { 38 | /* 39 | Internal representation of ref-counted array. The TNT 40 | arrays all use this building block. 41 | 42 |

43 | If an array block is created by TNT, then every time 44 | an assignment is made, the left-hand-side reference 45 | is decreased by one, and the right-hand-side refernce 46 | count is increased by one. If the array block was 47 | external to TNT, the refernce count is a NULL pointer 48 | regardless of how many references are made, since the 49 | memory is not freed by TNT. 50 | 51 | 52 | 53 | */ 54 | template 55 | class i_refvec 56 | { 57 | 58 | 59 | private: 60 | T* data_; 61 | int *ref_count_; 62 | 63 | 64 | public: 65 | 66 | i_refvec(); 67 | explicit i_refvec(int n); 68 | inline i_refvec(T* data); 69 | inline i_refvec(const i_refvec &v); 70 | inline T* begin(); 71 | inline const T* begin() const; 72 | inline T& operator[](int i); 73 | inline const T& operator[](int i) const; 74 | inline i_refvec & operator=(const i_refvec &V); 75 | void copy_(T* p, const T* q, const T* e); 76 | void set_(T* p, const T* b, const T* e); 77 | inline int ref_count() const; 78 | inline int is_null() const; 79 | inline void destroy(); 80 | ~i_refvec(); 81 | 82 | }; 83 | 84 | template 85 | void i_refvec::copy_(T* p, const T* q, const T* e) 86 | { 87 | for (T* t=p; q 92 | i_refvec::i_refvec() : data_(NULL), ref_count_(NULL) {} 93 | 94 | /** 95 | In case n is 0 or negative, it does NOT call new. 96 | */ 97 | template 98 | i_refvec::i_refvec(int n) : data_(NULL), ref_count_(NULL) 99 | { 100 | if (n >= 1) 101 | { 102 | #ifdef TNT_DEBUG 103 | std::cout << "new data storage.\n"; 104 | #endif 105 | data_ = new T[n]; 106 | ref_count_ = new int; 107 | *ref_count_ = 1; 108 | } 109 | } 110 | 111 | template 112 | inline i_refvec::i_refvec(const i_refvec &V): data_(V.data_), 113 | ref_count_(V.ref_count_) 114 | { 115 | if (V.ref_count_ != NULL) 116 | (*(V.ref_count_))++; 117 | } 118 | 119 | 120 | template 121 | i_refvec::i_refvec(T* data) : data_(data), ref_count_(NULL) {} 122 | 123 | template 124 | inline T* i_refvec::begin() 125 | { 126 | return data_; 127 | } 128 | 129 | template 130 | inline const T& i_refvec::operator[](int i) const 131 | { 132 | return data_[i]; 133 | } 134 | 135 | template 136 | inline T& i_refvec::operator[](int i) 137 | { 138 | return data_[i]; 139 | } 140 | 141 | 142 | template 143 | inline const T* i_refvec::begin() const 144 | { 145 | return data_; 146 | } 147 | 148 | 149 | 150 | template 151 | i_refvec & i_refvec::operator=(const i_refvec &V) 152 | { 153 | if (this == &V) 154 | return *this; 155 | 156 | 157 | if (ref_count_ != NULL) 158 | { 159 | (*ref_count_) --; 160 | if ((*ref_count_) == 0) 161 | destroy(); 162 | } 163 | 164 | data_ = V.data_; 165 | ref_count_ = V.ref_count_; 166 | 167 | if (V.ref_count_ != NULL) 168 | (*(V.ref_count_))++; 169 | 170 | return *this; 171 | } 172 | 173 | template 174 | void i_refvec::destroy() 175 | { 176 | if (ref_count_ != NULL) 177 | { 178 | #ifdef TNT_DEBUG 179 | std::cout << "destorying data... \n"; 180 | #endif 181 | delete ref_count_; 182 | 183 | #ifdef TNT_DEBUG 184 | std::cout << "deleted ref_count_ ...\n"; 185 | #endif 186 | if (data_ != NULL) 187 | delete []data_; 188 | #ifdef TNT_DEBUG 189 | std::cout << "deleted data_[] ...\n"; 190 | #endif 191 | data_ = NULL; 192 | } 193 | } 194 | 195 | /* 196 | * return 1 is vector is empty, 0 otherwise 197 | * 198 | * if is_null() is false and ref_count() is 0, then 199 | * 200 | */ 201 | template 202 | int i_refvec::is_null() const 203 | { 204 | return (data_ == NULL ? 1 : 0); 205 | } 206 | 207 | /* 208 | * returns -1 if data is external, 209 | * returns 0 if a is NULL array, 210 | * otherwise returns the positive number of vectors sharing 211 | * this data space. 212 | */ 213 | template 214 | int i_refvec::ref_count() const 215 | { 216 | if (data_ == NULL) 217 | return 0; 218 | else 219 | return (ref_count_ != NULL ? *ref_count_ : -1) ; 220 | } 221 | 222 | template 223 | i_refvec::~i_refvec() 224 | { 225 | if (ref_count_ != NULL) 226 | { 227 | (*ref_count_)--; 228 | 229 | if (*ref_count_ == 0) 230 | destroy(); 231 | } 232 | } 233 | 234 | 235 | } /* namespace TNT */ 236 | 237 | 238 | 239 | 240 | 241 | #endif 242 | /* TNT_I_REFVEC_H */ 243 | 244 | -------------------------------------------------------------------------------- /src/TNT/tnt_math_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef MATH_UTILS_H 2 | #define MATH_UTILS_H 3 | 4 | /* needed for fabs, sqrt() below */ 5 | #include 6 | 7 | 8 | 9 | namespace TNT 10 | { 11 | /** 12 | @returns hypotenuse of real (non-complex) scalars a and b by 13 | avoiding underflow/overflow 14 | using (a * sqrt( 1 + (b/a) * (b/a))), rather than 15 | sqrt(a*a + b*b). 16 | */ 17 | template 18 | Real hypot(const Real &a, const Real &b) 19 | { 20 | 21 | if (a== 0) 22 | return abs(b); 23 | else 24 | { 25 | Real c = b/a; 26 | return fabs(a) * sqrt(1 + c*c); 27 | } 28 | } 29 | } /* TNT namespace */ 30 | 31 | 32 | 33 | #endif 34 | /* MATH_UTILS_H */ 35 | -------------------------------------------------------------------------------- /src/TNT/tnt_sparse_matrix_csr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_SPARSE_MATRIX_CSR_H 22 | #define TNT_SPARSE_MATRIX_CSR_H 23 | 24 | #include "tnt_array1d.h" 25 | 26 | namespace TNT 27 | { 28 | 29 | 30 | /** 31 | Read-only view of a sparse matrix in compressed-row storage 32 | format. Neither array elements (nonzeros) nor sparsity 33 | structure can be modified. If modifications are required, 34 | create a new view. 35 | 36 |

37 | Index values begin at 0. 38 | 39 |

40 | Storage requirements: An (m x n) matrix with 41 | nz nonzeros requires no more than ((T+I)*nz + M*I) 42 | bytes, where T is the size of data elements and 43 | I is the size of integers. 44 | 45 | 46 | */ 47 | template 48 | class Sparse_Matrix_CompRow { 49 | 50 | private: 51 | Array1D val_; // data values (nz_ elements) 52 | Array1D rowptr_; // row_ptr (dim_[0]+1 elements) 53 | Array1D colind_; // col_ind (nz_ elements) 54 | 55 | int dim1_; // number of rows 56 | int dim2_; // number of cols 57 | 58 | public: 59 | 60 | Sparse_Matrix_CompRow(const Sparse_Matrix_CompRow &S); 61 | Sparse_Matrix_CompRow(int M, int N, int nz, const T *val, 62 | const int *r, const int *c); 63 | 64 | 65 | 66 | inline const T& val(int i) const { return val_[i]; } 67 | inline const int& row_ptr(int i) const { return rowptr_[i]; } 68 | inline const int& col_ind(int i) const { return colind_[i];} 69 | 70 | inline int dim1() const {return dim1_;} 71 | inline int dim2() const {return dim2_;} 72 | int NumNonzeros() const {return val_.dim1();} 73 | 74 | 75 | Sparse_Matrix_CompRow& operator=( 76 | const Sparse_Matrix_CompRow &R); 77 | 78 | 79 | 80 | }; 81 | 82 | /** 83 | Construct a read-only view of existing sparse matrix in 84 | compressed-row storage format. 85 | 86 | @param M the number of rows of sparse matrix 87 | @param N the number of columns of sparse matrix 88 | @param nz the number of nonzeros 89 | @param val a contiguous list of nonzero values 90 | @param r row-pointers: r[i] denotes the begining position of row i 91 | (i.e. the ith row begins at val[row[i]]). 92 | @param c column-indices: c[i] denotes the column location of val[i] 93 | */ 94 | template 95 | Sparse_Matrix_CompRow::Sparse_Matrix_CompRow(int M, int N, int nz, 96 | const T *val, const int *r, const int *c) : val_(nz,val), 97 | rowptr_(M, r), colind_(nz, c), dim1_(M), dim2_(N) {} 98 | 99 | 100 | } 101 | // namespace TNT 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/TNT/tnt_stopwatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Mathematical and Computational Sciences Division 4 | * National Institute of Technology, 5 | * Gaithersburg, MD USA 6 | * 7 | * 8 | * This software was developed at the National Institute of Standards and 9 | * Technology (NIST) by employees of the Federal Government in the course 10 | * of their official duties. Pursuant to title 17 Section 105 of the 11 | * United States Code, this software is not subject to copyright protection 12 | * and is in the public domain. NIST assumes no responsibility whatsoever for 13 | * its use by other parties, and makes no guarantees, expressed or implied, 14 | * about its quality, reliability, or any other characteristic. 15 | * 16 | */ 17 | 18 | 19 | 20 | #ifndef STOPWATCH_H 21 | #define STOPWATCH_H 22 | 23 | // for clock() and CLOCKS_PER_SEC 24 | #include 25 | 26 | 27 | namespace TNT 28 | { 29 | 30 | inline static double seconds(void) 31 | { 32 | const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; 33 | return ( (double) clock() ) * secs_per_tick; 34 | } 35 | 36 | class Stopwatch { 37 | private: 38 | int running_; 39 | double start_time_; 40 | double total_; 41 | 42 | public: 43 | inline Stopwatch(); 44 | inline void start(); 45 | inline double stop(); 46 | inline double read(); 47 | inline void resume(); 48 | inline int running(); 49 | }; 50 | 51 | inline Stopwatch::Stopwatch() : running_(0), start_time_(0.0), total_(0.0) {} 52 | 53 | void Stopwatch::start() 54 | { 55 | running_ = 1; 56 | total_ = 0.0; 57 | start_time_ = seconds(); 58 | } 59 | 60 | double Stopwatch::stop() 61 | { 62 | if (running_) 63 | { 64 | total_ += (seconds() - start_time_); 65 | running_ = 0; 66 | } 67 | return total_; 68 | } 69 | 70 | inline void Stopwatch::resume() 71 | { 72 | if (!running_) 73 | { 74 | start_time_ = seconds(); 75 | running_ = 1; 76 | } 77 | } 78 | 79 | 80 | inline double Stopwatch::read() 81 | { 82 | if (running_) 83 | { 84 | stop(); 85 | resume(); 86 | } 87 | return total_; 88 | } 89 | 90 | 91 | } /* TNT namespace */ 92 | #endif 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /src/TNT/tnt_subscript.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | #ifndef TNT_SUBSCRPT_H 22 | #define TNT_SUBSCRPT_H 23 | 24 | 25 | //--------------------------------------------------------------------- 26 | // This definition describes the default TNT data type used for 27 | // indexing into TNT matrices and vectors. The data type should 28 | // be wide enough to index into large arrays. It defaults to an 29 | // "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE, 30 | // e.g. 31 | // 32 | // c++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ... 33 | // 34 | //--------------------------------------------------------------------- 35 | // 36 | 37 | #ifndef TNT_SUBSCRIPT_TYPE 38 | #define TNT_SUBSCRIPT_TYPE int 39 | #endif 40 | 41 | namespace TNT 42 | { 43 | typedef TNT_SUBSCRIPT_TYPE Subscript; 44 | } /* namespace TNT */ 45 | 46 | 47 | // () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the 48 | // first elements. This offset is left as a macro for future 49 | // purposes, but should not be changed in the current release. 50 | // 51 | // 52 | #define TNT_BASE_OFFSET (1) 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/TNT/tnt_vec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Template Numerical Toolkit (TNT) 4 | * 5 | * Mathematical and Computational Sciences Division 6 | * National Institute of Technology, 7 | * Gaithersburg, MD USA 8 | * 9 | * 10 | * This software was developed at the National Institute of Standards and 11 | * Technology (NIST) by employees of the Federal Government in the course 12 | * of their official duties. Pursuant to title 17 Section 105 of the 13 | * United States Code, this software is not subject to copyright protection 14 | * and is in the public domain. NIST assumes no responsibility whatsoever for 15 | * its use by other parties, and makes no guarantees, expressed or implied, 16 | * about its quality, reliability, or any other characteristic. 17 | * 18 | */ 19 | 20 | 21 | 22 | #ifndef TNT_VEC_H 23 | #define TNT_VEC_H 24 | 25 | #include "tnt_subscript.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | namespace TNT 32 | { 33 | 34 | /** 35 | [Deprecatred] Value-based vector class from pre-1.0 36 | TNT version. Kept here for backward compatiblity, but should 37 | use the newer TNT::Array1D classes instead. 38 | 39 | */ 40 | 41 | template 42 | class Vector 43 | { 44 | 45 | 46 | public: 47 | 48 | typedef Subscript size_type; 49 | typedef T value_type; 50 | typedef T element_type; 51 | typedef T* pointer; 52 | typedef T* iterator; 53 | typedef T& reference; 54 | typedef const T* const_iterator; 55 | typedef const T& const_reference; 56 | 57 | Subscript lbound() const { return 1;} 58 | 59 | protected: 60 | T* v_; 61 | T* vm1_; // pointer adjustment for optimzied 1-offset indexing 62 | Subscript n_; 63 | 64 | // internal helper function to create the array 65 | // of row pointers 66 | 67 | void initialize(Subscript N) 68 | { 69 | // adjust pointers so that they are 1-offset: 70 | // v_[] is the internal contiguous array, it is still 0-offset 71 | // 72 | assert(v_ == NULL); 73 | v_ = new T[N]; 74 | assert(v_ != NULL); 75 | vm1_ = v_-1; 76 | n_ = N; 77 | } 78 | 79 | void copy(const T* v) 80 | { 81 | Subscript N = n_; 82 | Subscript i; 83 | 84 | #ifdef TNT_UNROLL_LOOPS 85 | Subscript Nmod4 = N & 3; 86 | Subscript N4 = N - Nmod4; 87 | 88 | for (i=0; i &A) : v_(0), vm1_(0), n_(0) 168 | { 169 | initialize(A.n_); 170 | copy(A.v_); 171 | } 172 | 173 | Vector(Subscript N, const T& value = T()) : v_(0), vm1_(0), n_(0) 174 | { 175 | initialize(N); 176 | set(value); 177 | } 178 | 179 | Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0) 180 | { 181 | initialize(N); 182 | copy(v); 183 | } 184 | 185 | Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0) 186 | { 187 | initialize(N); 188 | std::istringstream ins(s); 189 | 190 | Subscript i; 191 | 192 | for (i=0; i> v_[i]; 194 | } 195 | 196 | 197 | // methods 198 | // 199 | Vector& newsize(Subscript N) 200 | { 201 | if (n_ == N) return *this; 202 | 203 | destroy(); 204 | initialize(N); 205 | 206 | return *this; 207 | } 208 | 209 | 210 | // assignments 211 | // 212 | Vector& operator=(const Vector &A) 213 | { 214 | if (v_ == A.v_) 215 | return *this; 216 | 217 | if (n_ == A.n_) // no need to re-alloc 218 | copy(A.v_); 219 | 220 | else 221 | { 222 | destroy(); 223 | initialize(A.n_); 224 | copy(A.v_); 225 | } 226 | 227 | return *this; 228 | } 229 | 230 | Vector& operator=(const T& scalar) 231 | { 232 | set(scalar); 233 | return *this; 234 | } 235 | 236 | inline Subscript dim() const 237 | { 238 | return n_; 239 | } 240 | 241 | inline Subscript size() const 242 | { 243 | return n_; 244 | } 245 | 246 | 247 | inline reference operator()(Subscript i) 248 | { 249 | #ifdef TNT_BOUNDS_CHECK 250 | assert(1<=i); 251 | assert(i <= n_) ; 252 | #endif 253 | return vm1_[i]; 254 | } 255 | 256 | inline const_reference operator() (Subscript i) const 257 | { 258 | #ifdef TNT_BOUNDS_CHECK 259 | assert(1<=i); 260 | assert(i <= n_) ; 261 | #endif 262 | return vm1_[i]; 263 | } 264 | 265 | inline reference operator[](Subscript i) 266 | { 267 | #ifdef TNT_BOUNDS_CHECK 268 | assert(0<=i); 269 | assert(i < n_) ; 270 | #endif 271 | return v_[i]; 272 | } 273 | 274 | inline const_reference operator[](Subscript i) const 275 | { 276 | #ifdef TNT_BOUNDS_CHECK 277 | assert(0<=i); 278 | 279 | 280 | 281 | 282 | 283 | 284 | assert(i < n_) ; 285 | #endif 286 | return v_[i]; 287 | } 288 | 289 | 290 | 291 | }; 292 | 293 | 294 | /* *************************** I/O ********************************/ 295 | 296 | template 297 | std::ostream& operator<<(std::ostream &s, const Vector &A) 298 | { 299 | Subscript N=A.dim(); 300 | 301 | s << N << "\n"; 302 | 303 | for (Subscript i=0; i 311 | std::istream & operator>>(std::istream &s, Vector &A) 312 | { 313 | 314 | Subscript N; 315 | 316 | s >> N; 317 | 318 | if ( !(N == A.size() )) 319 | { 320 | A.newsize(N); 321 | } 322 | 323 | 324 | for (Subscript i=0; i> A[i]; 326 | 327 | 328 | return s; 329 | } 330 | 331 | // *******************[ basic matrix algorithms ]*************************** 332 | 333 | 334 | template 335 | Vector operator+(const Vector &A, 336 | const Vector &B) 337 | { 338 | Subscript N = A.dim(); 339 | 340 | assert(N==B.dim()); 341 | 342 | Vector tmp(N); 343 | Subscript i; 344 | 345 | for (i=0; i 352 | Vector operator-(const Vector &A, 353 | const Vector &B) 354 | { 355 | Subscript N = A.dim(); 356 | 357 | assert(N==B.dim()); 358 | 359 | Vector tmp(N); 360 | Subscript i; 361 | 362 | for (i=0; i 369 | Vector operator*(const Vector &A, 370 | const Vector &B) 371 | { 372 | Subscript N = A.dim(); 373 | 374 | assert(N==B.dim()); 375 | 376 | Vector tmp(N); 377 | Subscript i; 378 | 379 | for (i=0; i 387 | T dot_prod(const Vector &A, const Vector &B) 388 | { 389 | Subscript N = A.dim(); 390 | assert(N == B.dim()); 391 | 392 | Subscript i; 393 | T sum = 0; 394 | 395 | for (i=0; i